From 3d0630c04a02b717715a260d58eb7d2748519e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 31 Oct 2020 00:25:32 +0100 Subject: [PATCH] Remove the HLSL fragment shader generator. The GLSL one can now do its job. --- CMakeLists.txt | 2 - GPU/Common/ShaderCommon.h | 3 - GPU/D3D11/DrawEngineD3D11.h | 1 - GPU/D3D11/StencilBufferD3D11.cpp | 1 - GPU/Directx9/FragmentShaderGeneratorHLSL.cpp | 574 ------------------- GPU/Directx9/FragmentShaderGeneratorHLSL.h | 24 - GPU/GPU.vcxproj | 2 - GPU/GPU.vcxproj.filters | 6 - UWP/GPU_UWP/GPU_UWP.vcxproj | 2 - UWP/GPU_UWP/GPU_UWP.vcxproj.filters | 2 - libretro/Makefile.common | 1 - unittest/TestShaderGenerators.cpp | 36 +- 12 files changed, 19 insertions(+), 635 deletions(-) delete mode 100644 GPU/Directx9/FragmentShaderGeneratorHLSL.cpp delete mode 100644 GPU/Directx9/FragmentShaderGeneratorHLSL.h diff --git a/CMakeLists.txt b/CMakeLists.txt index adfad87ca3..2ad5fbdfeb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1300,8 +1300,6 @@ set(GPU_D3D9 GPU/Directx9/TextureCacheDX9.h GPU/Directx9/TextureScalerDX9.cpp GPU/Directx9/TextureScalerDX9.h - GPU/Directx9/FragmentShaderGeneratorHLSL.cpp - GPU/Directx9/FragmentShaderGeneratorHLSL.h GPU/Directx9/VertexShaderGeneratorHLSL.cpp GPU/Directx9/VertexShaderGeneratorHLSL.h ) diff --git a/GPU/Common/ShaderCommon.h b/GPU/Common/ShaderCommon.h index 9ca974cd2e..d757ff9d20 100644 --- a/GPU/Common/ShaderCommon.h +++ b/GPU/Common/ShaderCommon.h @@ -30,9 +30,6 @@ enum ShaderLanguage { GLSL_VULKAN, HLSL_D3D9, HLSL_D3D11, - - HLSL_D3D11_TEST, // temporary - HLSL_D3D9_TEST, // temporary }; inline bool ShaderLanguageIsOpenGL(ShaderLanguage lang) { diff --git a/GPU/D3D11/DrawEngineD3D11.h b/GPU/D3D11/DrawEngineD3D11.h index 5225c11052..47302fe71e 100644 --- a/GPU/D3D11/DrawEngineD3D11.h +++ b/GPU/D3D11/DrawEngineD3D11.h @@ -28,7 +28,6 @@ #include "GPU/Common/VertexDecoderCommon.h" #include "GPU/Common/DrawEngineCommon.h" #include "GPU/Common/GPUStateUtils.h" -#include "GPU/Directx9/FragmentShaderGeneratorHLSL.h" #include "GPU/D3D11/StateMappingD3D11.h" #include "GPU/D3D11/D3D11Util.h" diff --git a/GPU/D3D11/StencilBufferD3D11.cpp b/GPU/D3D11/StencilBufferD3D11.cpp index 043cbd50d0..118dba0dc5 100644 --- a/GPU/D3D11/StencilBufferD3D11.cpp +++ b/GPU/D3D11/StencilBufferD3D11.cpp @@ -23,7 +23,6 @@ #include "Core/Reporting.h" #include "GPU/Common/StencilCommon.h" #include "GPU/D3D11/FramebufferManagerD3D11.h" -#include "GPU/Directx9/FragmentShaderGeneratorHLSL.h" #include "GPU/D3D11/ShaderManagerD3D11.h" #include "GPU/D3D11/TextureCacheD3D11.h" #include "GPU/D3D11/D3D11Util.h" diff --git a/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp b/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp deleted file mode 100644 index 9cb577c94a..0000000000 --- a/GPU/Directx9/FragmentShaderGeneratorHLSL.cpp +++ /dev/null @@ -1,574 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// 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, version 2.0 or later versions. - -// 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 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#include - -#include "Core/Reporting.h" -#include "Core/Config.h" -#include "GPU/Directx9/FragmentShaderGeneratorHLSL.h" -#include "GPU/ge_constants.h" -#include "GPU/Common/GPUStateUtils.h" -#include "GPU/GPUState.h" -#include "GPU/Common/ShaderUniforms.h" - -#define WRITE p+=sprintf - -// #define DEBUG_SHADER - -extern const char *hlsl_preamble_fs; -extern const char *hlsl_d3d9_preamble_fs; -extern const char *hlsl_d3d11_preamble_fs; - -// Missing: Z depth range -// Also, logic ops etc, of course, as they are not supported in DX9. -bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguage lang, std::string *errorString) { - char *p = buffer; - - bool lmode = id.Bit(FS_BIT_LMODE); - bool doTexture = id.Bit(FS_BIT_DO_TEXTURE); - bool enableFog = id.Bit(FS_BIT_ENABLE_FOG); - bool enableAlphaTest = id.Bit(FS_BIT_ALPHA_TEST); - - bool alphaTestAgainstZero = id.Bit(FS_BIT_ALPHA_AGAINST_ZERO); - bool testForceToZero = id.Bit(FS_BIT_TEST_DISCARD_TO_ZERO); - bool enableColorTest = id.Bit(FS_BIT_COLOR_TEST); - bool colorTestAgainstZero = id.Bit(FS_BIT_COLOR_AGAINST_ZERO); - bool enableColorDoubling = id.Bit(FS_BIT_COLOR_DOUBLE); - bool doTextureProjection = id.Bit(FS_BIT_DO_TEXTURE_PROJ); - bool doTextureAlpha = id.Bit(FS_BIT_TEXALPHA); - bool doFlatShading = id.Bit(FS_BIT_FLATSHADE); - bool isModeClear = id.Bit(FS_BIT_CLEARMODE); - - bool bgraTexture = id.Bit(FS_BIT_BGRA_TEXTURE); - - GEComparison alphaTestFunc = (GEComparison)id.Bits(FS_BIT_ALPHA_TEST_FUNC, 3); - GEComparison colorTestFunc = (GEComparison)id.Bits(FS_BIT_COLOR_TEST_FUNC, 2); - bool needShaderTexClamp = id.Bit(FS_BIT_SHADER_TEX_CLAMP); - - ReplaceBlendType replaceBlend = static_cast(id.Bits(FS_BIT_REPLACE_BLEND, 3)); - ReplaceAlphaType stencilToAlpha = static_cast(id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2)); - - GETexFunc texFunc = (GETexFunc)id.Bits(FS_BIT_TEXFUNC, 3); - bool textureAtOffset = id.Bit(FS_BIT_TEXTURE_AT_OFFSET); - - GEBlendSrcFactor replaceBlendFuncA = (GEBlendSrcFactor)id.Bits(FS_BIT_BLENDFUNC_A, 4); - GEBlendDstFactor replaceBlendFuncB = (GEBlendDstFactor)id.Bits(FS_BIT_BLENDFUNC_B, 4); - GEBlendMode replaceBlendEq = (GEBlendMode)id.Bits(FS_BIT_BLENDEQ, 3); - - StencilValueType replaceAlphaWithStencilType = (StencilValueType)id.Bits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4); - - WRITE(p, "%s", hlsl_preamble_fs); - - // Output some compatibility defines - switch (lang) { - case ShaderLanguage::HLSL_D3D9: - WRITE(p, hlsl_d3d9_preamble_fs); - break; - case ShaderLanguage::HLSL_D3D11: - WRITE(p, hlsl_d3d11_preamble_fs); - break; - } - - if (lang == HLSL_D3D9) { - if (doTexture) - WRITE(p, "sampler tex : register(s0);\n"); - if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) { - if (replaceBlend == REPLACE_BLEND_COPY_FBO) { - WRITE(p, "vec2 u_fbotexSize : register(c%i);\n", CONST_PS_FBOTEXSIZE); - WRITE(p, "sampler fbotex : register(s1);\n"); - } - if (replaceBlendFuncA >= GE_SRCBLEND_FIXA) { - WRITE(p, "float3 u_blendFixA : register(c%i);\n", CONST_PS_BLENDFIXA); - } - if (replaceBlendFuncB >= GE_DSTBLEND_FIXB) { - WRITE(p, "float3 u_blendFixB : register(c%i);\n", CONST_PS_BLENDFIXB); - } - } - if (needShaderTexClamp && doTexture) { - WRITE(p, "vec4 u_texclamp : register(c%i);\n", CONST_PS_TEXCLAMP); - if (textureAtOffset) { - WRITE(p, "vec2 u_texclampoff : register(c%i);\n", CONST_PS_TEXCLAMPOFF); - } - } - - if (enableAlphaTest || enableColorTest) { - WRITE(p, "vec4 u_alphacolorref : register(c%i);\n", CONST_PS_ALPHACOLORREF); - WRITE(p, "vec4 u_alphacolormask : register(c%i);\n", CONST_PS_ALPHACOLORMASK); - } - if (stencilToAlpha && replaceAlphaWithStencilType == STENCIL_VALUE_UNIFORM) { - WRITE(p, "float u_stencilReplaceValue : register(c%i);\n", CONST_PS_STENCILREPLACE); - } - if (doTexture && texFunc == GE_TEXFUNC_BLEND) { - WRITE(p, "float3 u_texenv : register(c%i);\n", CONST_PS_TEXENV); - } - if (enableFog) { - WRITE(p, "float3 u_fogcolor : register(c%i);\n", CONST_PS_FOGCOLOR); - } - } else { - WRITE(p, "SamplerState samp : register(s0);\n"); - WRITE(p, "Texture2D tex : register(t0);\n"); - if (!isModeClear && replaceBlend > REPLACE_BLEND_STANDARD) { - if (replaceBlend == REPLACE_BLEND_COPY_FBO) { - // No sampler required, we Load - WRITE(p, "Texture2D fboTex : register(t1);\n"); - } - } - WRITE(p, "cbuffer base : register(b0) {\n%s};\n", cb_baseStr); - } - - if (enableAlphaTest) { - if (lang == HLSL_D3D11) { - WRITE(p, "int roundAndScaleTo255i(float x) { return int(floor(x * 255.0f + 0.5f)); }\n"); - } else { - // D3D11 level 9 gets to take this path. - WRITE(p, "float roundAndScaleTo255f(float x) { return floor(x * 255.0f + 0.5f); }\n"); - } - } - if (enableColorTest) { - if (lang == HLSL_D3D11) { - WRITE(p, "uvec3 roundAndScaleTo255iv(float3 x) { return uvec3(floor(x * 255.0f + 0.5f)); }\n"); - } else { - WRITE(p, "vec3 roundAndScaleTo255v(float3 x) { return floor(x * 255.0f + 0.5f); }\n"); - } - } - - WRITE(p, "struct PS_IN {\n"); - if (doTexture) { - WRITE(p, " vec3 v_texcoord: TEXCOORD0;\n"); - } - const char *colorInterpolation = doFlatShading && lang == HLSL_D3D11 ? "nointerpolation " : ""; - WRITE(p, " %svec4 v_color0: COLOR0;\n", colorInterpolation); - if (lmode) { - WRITE(p, " vec3 v_color1: COLOR1;\n"); - } - if (enableFog) { - WRITE(p, " float v_fogdepth: TEXCOORD1;\n"); - } - if (lang == HLSL_D3D11 && ((replaceBlend == REPLACE_BLEND_COPY_FBO) || gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT))) { - WRITE(p, " vec4 pixelPos : SV_POSITION;\n"); - } - WRITE(p, "};\n"); - - if (lang == HLSL_D3D9) { - WRITE(p, "vec4 main( PS_IN In ) : COLOR {\n"); - } else { - WRITE(p, "struct PS_OUT {\n"); - if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE) { - WRITE(p, " vec4 target : SV_Target0;\n"); - WRITE(p, " vec4 target1 : SV_Target1;\n"); - } - else { - WRITE(p, " vec4 target : SV_Target;\n"); - } - if (gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT)) { - WRITE(p, " float depth : SV_DEPTH;\n"); - } - WRITE(p, "};\n"); - WRITE(p, "PS_OUT main( PS_IN In ) {\n"); - WRITE(p, " PS_OUT outfragment;\n"); - } - - if (isModeClear) { - // Clear mode does not allow any fancy shading. - WRITE(p, " vec4 v = In.v_color0;\n"); - } else { - const char *secondary = ""; - // Secondary color for specular on top of texture - if (lmode) { - WRITE(p, " vec4 s = vec4(In.v_color1, 0.0);\n"); - secondary = " + s"; - } else { - secondary = ""; - } - - if (doTexture) { - const char *texcoord = "In.v_texcoord"; - // TODO: Not sure the right way to do this for projection. - if (needShaderTexClamp) { - // We may be clamping inside a larger surface (tex = 64x64, buffer=480x272). - // We may also be wrapping in such a surface, or either one in a too-small surface. - // Obviously, clamping to a smaller surface won't work. But better to clamp to something. - std::string ucoord = "In.v_texcoord.x"; - std::string vcoord = "In.v_texcoord.y"; - if (doTextureProjection) { - ucoord = "(In.v_texcoord.x / In.v_texcoord.z)"; - vcoord = "(In.v_texcoord.y / In.v_texcoord.z)"; - } - - if (id.Bit(FS_BIT_CLAMP_S)) { - ucoord = "clamp(" + ucoord + ", u_texclamp.z, u_texclamp.x - u_texclamp.z)"; - } else { - ucoord = "mod(" + ucoord + ", u_texclamp.x)"; - } - if (id.Bit(FS_BIT_CLAMP_T)) { - vcoord = "clamp(" + vcoord + ", u_texclamp.w, u_texclamp.y - u_texclamp.w)"; - } else { - vcoord = "mod(" + vcoord + ", u_texclamp.y)"; - } - if (textureAtOffset) { - ucoord = "(" + ucoord + " + u_texclampoff.x)"; - vcoord = "(" + vcoord + " + u_texclampoff.y)"; - } - - WRITE(p, " vec2 fixedcoord = vec2(%s, %s);\n", ucoord.c_str(), vcoord.c_str()); - texcoord = "fixedcoord"; - // We already projected it. - doTextureProjection = false; - } - - if (lang == HLSL_D3D11) { - if (doTextureProjection) { - WRITE(p, " vec4 t = tex.Sample(samp, In.v_texcoord.xy / In.v_texcoord.z)%s;\n", bgraTexture ? ".bgra" : ""); - } else { - WRITE(p, " vec4 t = tex.Sample(samp, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : ""); - } - } else { - if (doTextureProjection) { - WRITE(p, " vec4 t = tex2Dproj(tex, vec4(In.v_texcoord.x, In.v_texcoord.y, 0, In.v_texcoord.z))%s;\n", bgraTexture ? ".bgra" : ""); - } else { - WRITE(p, " vec4 t = tex2D(tex, %s.xy)%s;\n", texcoord, bgraTexture ? ".bgra" : ""); - } - } - if (texFunc != GE_TEXFUNC_REPLACE || !doTextureAlpha) { - WRITE(p, " vec4 p = In.v_color0;\n"); - } - - if (doTextureAlpha) { // texfmt == RGBA - switch (texFunc) { - case GE_TEXFUNC_MODULATE: - WRITE(p, " vec4 v = p * t%s;\n", secondary); break; - case GE_TEXFUNC_DECAL: - WRITE(p, " vec4 v = vec4(mix(p.rgb, t.rgb, t.a), p.a)%s;\n", secondary); break; - case GE_TEXFUNC_BLEND: - WRITE(p, " vec4 v = vec4(mix(p.rgb, u_texenv.rgb, t.rgb), p.a * t.a)%s;\n", secondary); break; - case GE_TEXFUNC_REPLACE: - WRITE(p, " vec4 v = t%s;\n", secondary); break; - case GE_TEXFUNC_ADD: - case GE_TEXFUNC_UNKNOWN1: - case GE_TEXFUNC_UNKNOWN2: - case GE_TEXFUNC_UNKNOWN3: - WRITE(p, " vec4 v = vec4(p.rgb + t.rgb, p.a * t.a)%s;\n", secondary); break; - default: - WRITE(p, " vec4 v = p;\n"); break; - } - - } else { // texfmt == RGB - switch (texFunc) { - case GE_TEXFUNC_MODULATE: - WRITE(p, " vec4 v = vec4(t.rgb * p.rgb, p.a)%s;\n", secondary); break; - case GE_TEXFUNC_DECAL: - WRITE(p, " vec4 v = vec4(t.rgb, p.a)%s;\n", secondary); break; - case GE_TEXFUNC_BLEND: - WRITE(p, " vec4 v = vec4(mix(p.rgb, u_texenv.rgb, t.rgb), p.a)%s;\n", secondary); break; - case GE_TEXFUNC_REPLACE: - WRITE(p, " vec4 v = vec4(t.rgb, p.a)%s;\n", secondary); break; - case GE_TEXFUNC_ADD: - case GE_TEXFUNC_UNKNOWN1: - case GE_TEXFUNC_UNKNOWN2: - case GE_TEXFUNC_UNKNOWN3: - WRITE(p, " vec4 v = vec4(p.rgb + t.rgb, p.a)%s;\n", secondary); break; - default: - WRITE(p, " vec4 v = p;\n"); break; - } - } - - if (enableColorDoubling) { - // This happens before fog is applied. - WRITE(p, " v.rgb = clamp(v.rgb * 2.0, 0.0, 1.0);\n"); - } - } else { - // No texture mapping - WRITE(p, " vec4 v = In.v_color0 %s;\n", secondary); - } - - if (enableFog) { - WRITE(p, " float fogCoef = clamp(In.v_fogdepth, 0.0, 1.0);\n"); - WRITE(p, " v = mix(vec4(u_fogcolor, v.a), v, fogCoef);\n"); - } - - const char *discardStatement = testForceToZero ? "v.a = 0.0;" : "DISCARD;"; - if (enableAlphaTest) { - if (alphaTestAgainstZero) { - // When testing against 0 (extremely common), we can avoid some math. - // 0.002 is approximately half of 1.0 / 255.0. - if (alphaTestFunc == GE_COMP_NOTEQUAL || alphaTestFunc == GE_COMP_GREATER) { - WRITE(p, " if (v.a < 0.002) %s\n", discardStatement); - } else if (alphaTestFunc != GE_COMP_NEVER) { - // Anything else is a test for == 0. Happens sometimes, actually... - WRITE(p, " if (v.a > 0.002) %s\n", discardStatement); - } else { - // NEVER has been logged as used by games, although it makes little sense - statically failing. - // Maybe we could discard the drawcall, but it's pretty rare. Let's just statically discard here. - WRITE(p, " %s\n", discardStatement); - } - } else { - const char *alphaTestFuncs[] = { "#", "#", " != ", " == ", " >= ", " > ", " <= ", " < " }; // never/always don't make sense - if (alphaTestFuncs[alphaTestFunc][0] != '#') { - // TODO: Rewrite this to use clip() appropriately (like, clip(v.a - u_alphacolorref.a)) - if (lang == HLSL_D3D11) { - WRITE(p, " if ((roundAndScaleTo255i(v.a) & u_alphacolormask.a) %s int(u_alphacolorref.a)) %s\n", alphaTestFuncs[alphaTestFunc], discardStatement); - } else { - // TODO: Use a texture to lookup bitwise ops? - WRITE(p, " if (roundAndScaleTo255f(v.a) %s u_alphacolorref.a) %s\n", alphaTestFuncs[alphaTestFunc], discardStatement); - } - } else { - // This means NEVER. See above. - WRITE(p, " %s\n", discardStatement); - } - } - } - - if (enableColorTest) { - if (colorTestAgainstZero) { - // When testing against 0 (common), we can avoid some math. - // 0.002 is approximately half of 1.0 / 255.0. - if (colorTestFunc == GE_COMP_NOTEQUAL) { - WRITE(p, " if (v.r < 0.002 && v.g < 0.002 && v.b < 0.002) %s\n", discardStatement); - } else if (colorTestFunc != GE_COMP_NEVER) { - // Anything else is a test for == 0. - WRITE(p, " if (v.r > 0.002 || v.g > 0.002 || v.b > 0.002) %s\n", discardStatement); - } else { - // NEVER has been logged as used by games, although it makes little sense - statically failing. - // Maybe we could discard the drawcall, but it's pretty rare. Let's just statically discard here. - WRITE(p, " %s\n", discardStatement); - } - } else { - const char *colorTestFuncs[] = { "#", "#", " != ", " == " }; // never/always don't make sense - if (colorTestFuncs[colorTestFunc][0] != '#') { - const char *test = colorTestFuncs[colorTestFunc]; - if (lang == HLSL_D3D11) { - WRITE(p, " uvec3 v_scaled = roundAndScaleTo255iv(v.rgb);\n"); - WRITE(p, " uvec3 v_masked = v_scaled & u_alphacolormask.rgb;\n"); - WRITE(p, " uvec3 colorTestRef = u_alphacolorref.rgb & u_alphacolormask.rgb;\n"); - // We have to test the components separately, or we get incorrect results. See #10629. - WRITE(p, " if (v_masked.r %s colorTestRef.r && v_masked.g %s colorTestRef.g && v_masked.b %s colorTestRef.b) %s\n", test, test, test, discardStatement); - } else { - // TODO: Use a texture to lookup bitwise ops instead? - WRITE(p, " vec3 colortest = roundAndScaleTo255v(v.rgb);\n"); - WRITE(p, " if ((colortest.r %s u_alphacolorref.r) && (colortest.g %s u_alphacolorref.g) && (colortest.b %s u_alphacolorref.b)) %s\n", test, test, test, discardStatement); - } - } - else { - WRITE(p, " %s\n", discardStatement); - } - } - } - - if (replaceBlend == REPLACE_BLEND_2X_SRC) { - WRITE(p, " v.rgb = v.rgb * 2.0;\n"); - } - - if (replaceBlend == REPLACE_BLEND_PRE_SRC || replaceBlend == REPLACE_BLEND_PRE_SRC_2X_ALPHA) { - const char *srcFactor = "ERROR"; - switch (replaceBlendFuncA) { - case GE_SRCBLEND_DSTCOLOR: srcFactor = "ERROR"; break; - case GE_SRCBLEND_INVDSTCOLOR: srcFactor = "ERROR"; break; - case GE_SRCBLEND_SRCALPHA: srcFactor = "splat3(v.a)"; break; - case GE_SRCBLEND_INVSRCALPHA: srcFactor = "splat3(1.0 - v.a)"; break; - case GE_SRCBLEND_DSTALPHA: srcFactor = "ERROR"; break; - case GE_SRCBLEND_INVDSTALPHA: srcFactor = "ERROR"; break; - case GE_SRCBLEND_DOUBLESRCALPHA: srcFactor = "splat3(v.a * 2.0)"; break; - case GE_SRCBLEND_DOUBLEINVSRCALPHA: srcFactor = "splat3(1.0 - v.a * 2.0)"; break; - // PRE_SRC for REPLACE_BLEND_PRE_SRC_2X_ALPHA means "double the src." - // It's close to the same, but clamping can still be an issue. - case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "splat3(2.0)"; break; - case GE_SRCBLEND_DOUBLEINVDSTALPHA: srcFactor = "ERROR"; break; - case GE_SRCBLEND_FIXA: srcFactor = "u_blendFixA"; break; - default: srcFactor = "u_blendFixA"; break; - } - if (!strcmp(srcFactor, "ERROR")) { - *errorString = "Bad srcfactor in replace blend"; - return false; - } - - WRITE(p, " v.rgb = v.rgb * %s;\n", srcFactor); - } - - if (lang == HLSL_D3D11 && replaceBlend == REPLACE_BLEND_COPY_FBO) { - WRITE(p, " vec4 destColor = fboTex.Load(int3((int)In.pixelPos.x, (int)In.pixelPos.y, 0));\n"); - - const char *srcFactor = nullptr; - const char *dstFactor = nullptr; - - switch (replaceBlendFuncA) { - case GE_SRCBLEND_DSTCOLOR: srcFactor = "destColor.rgb"; break; - case GE_SRCBLEND_INVDSTCOLOR: srcFactor = "(splat3(1.0) - destColor.rgb)"; break; - case GE_SRCBLEND_SRCALPHA: srcFactor = "v.aaa"; break; - case GE_SRCBLEND_INVSRCALPHA: srcFactor = "splat3(1.0 - v.a)"; break; - case GE_SRCBLEND_DSTALPHA: srcFactor = "destColor.aaa"; break; - case GE_SRCBLEND_INVDSTALPHA: srcFactor = "splat3(1.0) - destColor.aaa"; break; - case GE_SRCBLEND_DOUBLESRCALPHA: srcFactor = "v.aaa * 2.0"; break; - case GE_SRCBLEND_DOUBLEINVSRCALPHA: srcFactor = "splat3(1.0) - v.aaa * 2.0"; break; - case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "destColor.aaa * 2.0"; break; - case GE_SRCBLEND_DOUBLEINVDSTALPHA: srcFactor = "splat3(1.0) - destColor.aaa * 2.0"; break; - case GE_SRCBLEND_FIXA: srcFactor = "u_blendFixA"; break; - default: srcFactor = "u_blendFixA"; break; - } - switch (replaceBlendFuncB) { - case GE_DSTBLEND_SRCCOLOR: dstFactor = "v.rgb"; break; - case GE_DSTBLEND_INVSRCCOLOR: dstFactor = "(splat3(1.0) - v.rgb)"; break; - case GE_DSTBLEND_SRCALPHA: dstFactor = "v.aaa"; break; - case GE_DSTBLEND_INVSRCALPHA: dstFactor = "splat3(1.0) - v.aaa"; break; - case GE_DSTBLEND_DSTALPHA: dstFactor = "destColor.aaa"; break; - case GE_DSTBLEND_INVDSTALPHA: dstFactor = "splat3(1.0) - destColor.aaa"; break; - case GE_DSTBLEND_DOUBLESRCALPHA: dstFactor = "v.aaa * 2.0"; break; - case GE_DSTBLEND_DOUBLEINVSRCALPHA: dstFactor = "splat3(1.0) - v.aaa * 2.0"; break; - case GE_DSTBLEND_DOUBLEDSTALPHA: dstFactor = "destColor.aaa * 2.0"; break; - case GE_DSTBLEND_DOUBLEINVDSTALPHA: dstFactor = "splat3(1.0) - destColor.aaa * 2.0"; break; - case GE_DSTBLEND_FIXB: dstFactor = "u_blendFixB"; break; - default: dstFactor = "u_blendFixB"; break; - } - - switch (replaceBlendEq) { - case GE_BLENDMODE_MUL_AND_ADD: - WRITE(p, " v.rgb = v.rgb * %s + destColor.rgb * %s;\n", srcFactor, dstFactor); - break; - case GE_BLENDMODE_MUL_AND_SUBTRACT: - WRITE(p, " v.rgb = v.rgb * %s - destColor.rgb * %s;\n", srcFactor, dstFactor); - break; - case GE_BLENDMODE_MUL_AND_SUBTRACT_REVERSE: - WRITE(p, " v.rgb = destColor.rgb * %s - v.rgb * %s;\n", dstFactor, srcFactor); - break; - case GE_BLENDMODE_MIN: - WRITE(p, " v.rgb = min(v.rgb, destColor.rgb);\n"); - break; - case GE_BLENDMODE_MAX: - WRITE(p, " v.rgb = max(v.rgb, destColor.rgb);\n"); - break; - case GE_BLENDMODE_ABSDIFF: - WRITE(p, " v.rgb = abs(v.rgb - destColor.rgb);\n"); - break; - default: - *errorString = "Bad replace blend eq"; - return false; - } - } - - // Can do REPLACE_BLEND_COPY_FBO in ps_2_0, but need to apply viewport in the vertex shader - // so that we can have the output position here to sample the texture at. - - if (replaceBlend == REPLACE_BLEND_2X_ALPHA || replaceBlend == REPLACE_BLEND_PRE_SRC_2X_ALPHA) { - WRITE(p, " v.a = v.a * 2.0;\n"); - } - } - - std::string replacedAlpha = "0.0"; - char replacedAlphaTemp[64] = ""; - if (stencilToAlpha != REPLACE_ALPHA_NO) { - switch (replaceAlphaWithStencilType) { - case STENCIL_VALUE_UNIFORM: - replacedAlpha = "u_stencilReplaceValue"; - break; - - case STENCIL_VALUE_ZERO: - replacedAlpha = "0.0"; - break; - - case STENCIL_VALUE_ONE: - case STENCIL_VALUE_INVERT: - // In invert, we subtract by one, but we want to output one here. - replacedAlpha = "1.0"; - break; - - case STENCIL_VALUE_INCR_4: - case STENCIL_VALUE_DECR_4: - // We're adding/subtracting, just by the smallest value in 4-bit. - snprintf(replacedAlphaTemp, sizeof(replacedAlphaTemp), "%f", 1.0 / 15.0); - replacedAlpha = replacedAlphaTemp; - break; - - case STENCIL_VALUE_INCR_8: - case STENCIL_VALUE_DECR_8: - // We're adding/subtracting, just by the smallest value in 8-bit. - snprintf(replacedAlphaTemp, sizeof(replacedAlphaTemp), "%f", 1.0 / 255.0); - replacedAlpha = replacedAlphaTemp; - break; - - case STENCIL_VALUE_KEEP: - // Do nothing. We'll mask out the alpha using color mask. - break; - } - } - - switch (stencilToAlpha) { - case REPLACE_ALPHA_DUALSOURCE: - // Handled at the end. - break; - - case REPLACE_ALPHA_YES: - WRITE(p, " v.a = %s;\n", replacedAlpha.c_str()); - break; - - case REPLACE_ALPHA_NO: - // Do nothing, v is already fine. - break; - - default: - *errorString = "Bad stencil-to-alpha type, corrupt ID?"; - return false; - } - - LogicOpReplaceType replaceLogicOpType = (LogicOpReplaceType)id.Bits(FS_BIT_REPLACE_LOGIC_OP_TYPE, 2); - switch (replaceLogicOpType) { - case LOGICOPTYPE_ONE: - WRITE(p, " v.rgb = splat3(1.0);\n"); - break; - case LOGICOPTYPE_INVERT: - WRITE(p, " v.rgb = splat3(1.0) - v.rgb;\n"); - break; - case LOGICOPTYPE_NORMAL: - break; - - default: - *errorString = "Bad logic op type, corrupt ID?"; - return false; - } - - if (gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT)) { - const double scale = DepthSliceFactor() * 65535.0; - - WRITE(p, " float z = In.pixelPos.z;\n"); - if (gstate_c.Supports(GPU_SUPPORTS_ACCURATE_DEPTH)) { - // We center the depth with an offset, but only its fraction matters. - // When (DepthSliceFactor() - 1) is odd, it will be 0.5, otherwise 0. - if (((int)(DepthSliceFactor() - 1.0f) & 1) == 1) { - WRITE(p, " z = (floor((z * %f) - (1.0 / 2.0)) + (1.0 / 2.0)) * (1.0 / %f);\n", scale, scale); - } else { - WRITE(p, " z = floor(z * %f) * (1.0 / %f);\n", scale, scale); - } - } else { - WRITE(p, " z = (1.0/65535.0) * floor(z * 65535.0);\n"); - } - WRITE(p, " outfragment.depth = z;\n"); - } - - if (lang == HLSL_D3D11) { - if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE) { - WRITE(p, " outfragment.target = vec4(v.rgb, %s);\n", replacedAlpha.c_str()); - WRITE(p, " outfragment.target1 = vec4(0.0, 0.0, 0.0, v.a);\n"); - WRITE(p, " return outfragment;\n"); - } - else { - WRITE(p, " outfragment.target = v;\n"); - WRITE(p, " return outfragment;\n"); - } - } else { - WRITE(p, " return v;\n"); - } - WRITE(p, "}\n"); - return true; -} diff --git a/GPU/Directx9/FragmentShaderGeneratorHLSL.h b/GPU/Directx9/FragmentShaderGeneratorHLSL.h deleted file mode 100644 index a3ec82cf14..0000000000 --- a/GPU/Directx9/FragmentShaderGeneratorHLSL.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2012- PPSSPP Project. - -// 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, version 2.0 or later versions. - -// 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 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#pragma once - -#include "GPU/Common/ShaderId.h" -#include "GPU/Common/ShaderCommon.h" -#include "GPU/GLES/FragmentShaderGeneratorGLES.h" - -bool GenerateFragmentShaderHLSL(const FShaderID &id, char *buffer, ShaderLanguage lang, std::string *errorString); diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index e63b0babdb..a407b12a0b 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -385,7 +385,6 @@ - @@ -560,7 +559,6 @@ - diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index 4df5470e9b..90f1f71525 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -273,9 +273,6 @@ DirectX9 - - DirectX9 - @@ -548,8 +545,5 @@ DirectX9 - - DirectX9 - \ No newline at end of file diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj index 6b735f6a38..64aa7c966f 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj @@ -416,7 +416,6 @@ - @@ -476,7 +475,6 @@ - diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters index 1a11e78ecd..dc84cf2ebb 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters @@ -41,7 +41,6 @@ - @@ -96,7 +95,6 @@ - diff --git a/libretro/Makefile.common b/libretro/Makefile.common index db8dbcd34f..839c6a9dba 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -661,7 +661,6 @@ ifeq ($(PLATFORM_EXT), win32) SOURCES_CXX += \ $(GPUDIR)/Directx9/DepalettizeShaderDX9.cpp \ $(GPUDIR)/Directx9/DrawEngineDX9.cpp \ - $(GPUDIR)/Directx9/FragmentShaderGeneratorHLSL.cpp \ $(GPUDIR)/Directx9/FramebufferManagerDX9.cpp \ $(GPUDIR)/Directx9/GPU_DX9.cpp \ $(GPUDIR)/Directx9/ShaderManagerDX9.cpp \ diff --git a/unittest/TestShaderGenerators.cpp b/unittest/TestShaderGenerators.cpp index c7691ce270..06156a9969 100644 --- a/unittest/TestShaderGenerators.cpp +++ b/unittest/TestShaderGenerators.cpp @@ -9,7 +9,6 @@ #include "GPU/Vulkan/VulkanContext.h" -#include "GPU/Directx9/FragmentShaderGeneratorHLSL.h" #include "GPU/GLES/FragmentShaderGeneratorGLES.h" #include "GPU/Directx9/VertexShaderGeneratorHLSL.h" @@ -24,10 +23,6 @@ bool GenerateFShader(FShaderID id, char *buffer, ShaderLanguage lang, std::string *errorString) { uint64_t uniformMask; switch (lang) { - case ShaderLanguage::HLSL_D3D11: - return GenerateFragmentShaderHLSL(id, buffer, ShaderLanguage::HLSL_D3D11, errorString); - case ShaderLanguage::HLSL_D3D9: - return GenerateFragmentShaderHLSL(id, buffer, ShaderLanguage::HLSL_D3D9, errorString); case ShaderLanguage::GLSL_VULKAN: { GLSLShaderCompat compat(ShaderLanguage::GLSL_VULKAN); @@ -45,12 +40,12 @@ bool GenerateFShader(FShaderID id, char *buffer, ShaderLanguage lang, std::strin return GenerateFragmentShaderGLSL(id, buffer, compat, &uniformMask, errorString); } - case ShaderLanguage::HLSL_D3D9_TEST: + case ShaderLanguage::HLSL_D3D9: { GLSLShaderCompat compat(ShaderLanguage::HLSL_D3D9); return GenerateFragmentShaderGLSL(id, buffer, compat, &uniformMask, errorString); } - case ShaderLanguage::HLSL_D3D11_TEST: + case ShaderLanguage::HLSL_D3D11: { GLSLShaderCompat compat(ShaderLanguage::HLSL_D3D11); return GenerateFragmentShaderGLSL(id, buffer, compat, &uniformMask, errorString); @@ -64,21 +59,28 @@ bool GenerateVShader(VShaderID id, char *buffer, ShaderLanguage lang, std::strin uint32_t attrMask; uint64_t uniformMask; switch (lang) { - case ShaderLanguage::HLSL_D3D11: - return GenerateVertexShaderHLSL(id, buffer, ShaderLanguage::HLSL_D3D11, errorString); - case ShaderLanguage::HLSL_D3D9: - return GenerateVertexShaderHLSL(id, buffer, ShaderLanguage::HLSL_D3D9, errorString); case ShaderLanguage::GLSL_VULKAN: { GLSLShaderCompat compat(ShaderLanguage::GLSL_VULKAN); return GenerateVertexShaderGLSL(id, buffer, compat, &attrMask, &uniformMask, errorString); } - case ShaderLanguage::HLSL_D3D9_TEST: + case ShaderLanguage::GLSL_140: + { + GLSLShaderCompat compat(ShaderLanguage::GLSL_140); + return GenerateVertexShaderGLSL(id, buffer, compat, &attrMask, &uniformMask, errorString); + } + + case ShaderLanguage::GLSL_300: + { + GLSLShaderCompat compat(ShaderLanguage::GLSL_140); + return GenerateVertexShaderGLSL(id, buffer, compat, &attrMask, &uniformMask, errorString); + } + case ShaderLanguage::HLSL_D3D9: { GLSLShaderCompat compat(ShaderLanguage::HLSL_D3D9); return GenerateVertexShaderGLSL(id, buffer, compat, &attrMask, &uniformMask, errorString); } - case ShaderLanguage::HLSL_D3D11_TEST: + case ShaderLanguage::HLSL_D3D11: { GLSLShaderCompat compat(ShaderLanguage::HLSL_D3D11); return GenerateVertexShaderGLSL(id, buffer, compat, &attrMask, &uniformMask, errorString); @@ -92,13 +94,11 @@ bool TestCompileShader(const char *buffer, ShaderLanguage lang, bool vertex, std std::vector spirv; switch (lang) { case ShaderLanguage::HLSL_D3D11: - case ShaderLanguage::HLSL_D3D11_TEST: { auto output = CompileShaderToBytecodeD3D11(buffer, strlen(buffer), vertex ? "vs_4_0" : "ps_4_0", 0); return !output.empty(); } case ShaderLanguage::HLSL_D3D9: - case ShaderLanguage::HLSL_D3D9_TEST: { LPD3DBLOB blob = CompileShaderToByteCodeD3D9(buffer, vertex ? "vs_2_0" : "ps_2_0", errorMessage); if (blob) { @@ -153,9 +153,7 @@ bool TestShaderGenerators() { LoadD3DCompilerDynamic(); ShaderLanguage languages[] = { - ShaderLanguage::HLSL_D3D9_TEST, ShaderLanguage::HLSL_D3D9, - ShaderLanguage::HLSL_D3D11_TEST, ShaderLanguage::HLSL_D3D11, ShaderLanguage::GLSL_VULKAN, ShaderLanguage::GLSL_140, @@ -237,6 +235,7 @@ bool TestShaderGenerators() { successes = 0; count = 200; + /* // Generate a bunch of random vertex shader IDs, try to generate shader source. // Then compile it and check that it's ok. for (int i = 0; i < count; i++) { @@ -287,6 +286,9 @@ bool TestShaderGenerators() { successes = 0; count = 200; + */ + + _CrtCheckMemory(); for (int i = 0; i < numLanguages; i++) { delete[] buffer[i];