From c28bbde053c5959be7bab602216c36789b2b3bd1 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Wed, 20 Feb 2019 14:36:07 +0100 Subject: [PATCH 01/81] Add more games to RequireBlockTransfer. Plus, for whatever reason we seem to have a separate compat.ini for UWP, update it. See #11558 --- UWP/Content/compat.ini | 419 +++++++++++++++++++++++++++++++++++++++-- assets/compat.ini | 10 + 2 files changed, 414 insertions(+), 15 deletions(-) diff --git a/UWP/Content/compat.ini b/UWP/Content/compat.ini index 00adc21e42..620f55b170 100644 --- a/UWP/Content/compat.ini +++ b/UWP/Content/compat.ini @@ -31,15 +31,31 @@ [VertexDepthRounding] # Phantasy Star Portable needs depth rounding to 16-bit precision for text to show up. # It's enough to do it at the vertex granularity. #3777 +# Phantasy Star Portable ULJM05309 = true ULUS10410 = true ULES01218 = true ULJM08023 = true ULES01218 = true -# Phantasy Star Portable 2 JP (missing text) +# Phantasy Star Portable 1 Demo +NPUH90023 = true +# Phantasy Star Portable 2 +ULES01439 = true +ULUS10529 = true ULJM05493 = true NPJH50043 = true ULJM08030 = true +NPUH90023 = true +ULJM91014 = true +NPJH90002 = true +ULJM05732 = true +NPJH50332 = true +# Phantasy Star Portable 2 JP Demo +ULJM91018 = true +NPJH90062 = true +# Phantasy Star Portable Infinity Demo +NPJH90157 = true # Infinity demo + # Puyo Puyo Fever 2 #3663 (layering) ULJM05058 = true # NBA 2K13 #6603 (menu glitches) @@ -48,6 +64,7 @@ ULJS00551 = true NPJH50713 = true ULJS00596 = true ULES01578 = true +ULUS10598 = true # Power Stone Collection #6257 (map arrow) ULES00496 = true ULUS10171 = true @@ -70,47 +87,83 @@ ULJS00454 = true # Heroes Phantasia Limited Edition Disc requires pixel depth rounding. ULJS00455 = true # Phantasy Star games flickering -# Phantasy Star Portable 1 +# Phantasy Star Portable ULJM05309 = true ULUS10410 = true ULES01218 = true ULJM08023 = true ULES01218 = true -# Phantasy Star Portable 2 JP +# Phantasy Star Portable 1 Demo +NPUH90023 = true +# Phantasy Star Portable 2 +ULES01439 = true +ULUS10529 = true ULJM05493 = true NPJH50043 = true ULJM08030 = true -# Phantasy Star Portable 1 Demo NPUH90023 = true ULJM91014 = true NPJH90002 = true +ULJM05732 = true +NPJH50332 = true # Phantasy Star Portable 2 JP Demo ULJM91018 = true NPJH90062 = true +# Phantasy Star Portable Infinity Demo +NPJH90157 = true # Infinity demo [DepthRangeHack] # Phantasy Star Portable 2 and Infinity both use viewport depth outside [0, 1]. # This gets clamped in our current implementation, but attempts to fix it run into # Other bugs, so we've restored this hack for now. +# Phantasy Star Portable +ULJM05309 = true +ULUS10410 = true +ULES01218 = true +ULJM08023 = true +ULES01218 = true +# Phantasy Star Portable 1 Demo +NPUH90023 = true +# Phantasy Star Portable 2 +ULES01439 = true +ULUS10529 = true ULJM05493 = true NPJH50043 = true ULJM08030 = true -ULES01439 = true -ULUS10529 = true -ULJM91018 = true # Infinity demo disc? -NPJH90157 = true # Infinity demo +NPUH90023 = true +ULJM91014 = true +NPJH90002 = true ULJM05732 = true NPJH50332 = true +# Phantasy Star Portable 2 JP Demo +ULJM91018 = true +NPJH90062 = true +# Phantasy Star Portable Infinity Demo +NPJH90157 = true # Infinity demo [ClearToRAM] # SOCOM Navy Seals games require this. See issue #8973. -# Navy Seals -UCUS98615 = true -ULES00038 = true -UCKS45021 = true -# Fireteam Bravo 3 -UCJS10102 = true +# Navy Seals : Tactical Strike +UCES00855 = true +UCUS98649 = true NPJG00035 = true +NPJG90068 = true +UCJS10102 = true +# Tactical Strike demo +NPUG70003 = true +# Fireteam Bravo +UCKS45021 = true +UCUS98615 = true +UCES00038 = true +ULES00038 = true +# Fireteam Bravo 2 +UCES00543 = true +UCUS98645 = true +# Fireteam Bravo 2 Demo +UCUS98677 = true +UCUS98691 = true +# Fireteam Bravo 3 +NPHG00032 = true UCUS98716 = true UCES01242 = true @@ -130,15 +183,25 @@ UCKS45022 = true ULJS19009 = true NPJH50141 = true +[DisableReadbacks] +# MotoGP copies the framebuffer to RAM every frame. We have a hack to display it directly, +# which means we don't also need a readback. +ULJS00078 = true +ULUS10153 = true +UCES00373 = true [DrawSyncEatCycles] # This replaced Crash Tag Team Racing hack to also fix Gundam games # It makes sceGeDrawSync eat a lot of cycles which can affect timing in lots of games, # might be negative for others, but happens to fix games below. # Crash Tag Team Racing needs it to pass checking memory stick screen. -ULUS10044 = true ULES00168 = true +ULES00169 = true +ULES00170 = true +ULES00171 = true +ULES00172 = true ULJM05036 = true +ULUS10044 = true # Gundam Battle Royale might need it to avoid crashes when certain Ace enemies shows up ULJS00083 = true ULKS46104 = true @@ -153,6 +216,14 @@ ULKS46183 = true ULJS00260 = true ULJS19041 = true NPJH50843 = true +# Helps with Jeanne d'Arc weird 40/40 fps problem #5154 +UCAS40129 = true +UCJS10048 = true +UCKS45033 = true +UCJS18014 = true +UCUS98700 = true +NPJG00032 = true +UCJX90019 = true [FakeMipmapChange] # This hacks separates each mipmap to independent textures to display wrong-size mipmaps. @@ -162,3 +233,321 @@ NPJH50843 = true ULJM05753 = true NPJH50348 = true ULJM06009 = true + +[RequireBufferedRendering] +# Warn the user that the game will not work and have issue, if buffered rendering is not enabled. +# Midnight Club: LA Remix +ULUS10383 = true +ULES01144 = true +ULJS00180 = true +ULJS00267 = true +ULJM05904 = true +NPJH50440 = true +# Midnight Club 3 : DUB edition +ULUS10021 = true +ULES00108 = true +# GTA : VCS +ULUS10160 = true +ULES00502 = true +ULJM05297 = true +ULJM05395 = true +ULJM05884 = true +NPJH50827 = true +# GTA : LCS +ULUS10041 = true +ULES00151 = true +ULJM05255 = true +ULJM05359 = true +ULJM05885 = true +NPJH50825 = true +# GOW : JP/Korean +UCJS10114 = true +UCKS45084 = true +# GOW : Ghost of Sparta +UCUS98737 = true +UCAS40323 = true +NPHG00092 = true +NPEG00044 = true +NPEG00045 = true +NPJG00120 = true +NPUG80508 = true +UCJS10114 = true +UCES01401 = true +UCES01473 = true +# GOW : Ghost of Sparta Demo +NPJG90095 = true +NPEG90035 = true +NPUG70125 = true +# GOW : Chains Of Olympus +UCAS40198 = true +UCUS98653 = true +UCES00842 = true +ULJM05438 = true +ULJM05348 = true +UCKS45084 = true +NPUG80325 = true +NPEG00023 = true +NPHG00027 = true +NPHG00028 = true +NPJH50170 = true +UCET00844 = true +# GOW: Chains of Olympus Demo +UCUS98705 = true +UCED00971 = true +UCUS98713 = true +# Daxter +UCUS98618 = true +UCES00044 = true +NPUG80329 = true +NPEG00025 = true +# Ys Seven +ULUS10551 = true +ULJM05475 = true +NPEH00065 = true +NPJH50350 = true +ULJM08041 = true +NPEH00065 = true +# The Legend of Heroes: Trails in the Sky +ULUS10540 = true +ULUS10578 = true +ULES01556 = true +ULJM05170 = true +ULJM08033 = true +NPJH50373 = true +# Grand Knights History +ULJS00394 = true +ULJS19068 = true +NPJH50518 = true +# Tactics Ogre +ULUS10565 = true +ULES01500 = true +ULJM05753 = true +NPJH50348 = true +ULJM06009 = true +UCKS45164 = true +# Metal Gear Solid : Peace Walker +ULUS10509 = true +ULES01372 = true +ULJM08038 = true +NPJH50045 = true +ULJM05630 = true +# Star Ocean : Second Evolution +ULUS10375 = true +ULES01187 = true +ULJM05591 = true +ULJM05325 = true +UCAS40203 = true +# Driver 76 +ULUS10235 = true +ULES00740 = true +# Chili Con Carnage +ULUS10216 = true +ULES00629 = true +# TODO: There are many more. + +[RequireBlockTransfer] +# Warn the user that the game will have issue graphic, if simulate block transfer is not enabled. +# Ys Seven need it to fix minimap. See issues #2928 +ULUS10551 = true +ULJM05475 = true +NPEH00065 = true +NPJH50350 = true +ULJM08041 = true +NPEH00065 = true +# The Legend of Heroes: Trails in the Sky need it to fix graphical glitch in menu screen. See issues #8053 +ULUS10540 = true +ULUS10578 = true +ULES01556 = true +ULJM05170 = true +ULJM08033 = true +NPJH50373 = true +NPUH10191 = true +NPUH10197 = true +# Grand Knights History need it to fix blackboxes on characters and flickering texture . See issues #2135 , #6099 +ULJS00394 = true +ULJS19068 = true +NPJH50518 = true +# TODO: Will add some games in the future +NPJH50686 = true # Digimon Adventures (JP, and English patches...) +ULJS00078 = true # MotoGP +ULUS10153 = true # MotoGP +UCES00373 = true # MotoGP +ULUS10551 = true # Ys Seven +ULJM05475 = true # Ys Seven JP +ULUS10549 = true # Ys Seven +NPEH00065 = true # Ys Seven +NPJH50350 = true # Ys Seven +ULJM08041 = true # Ys Seven + +[DisableAccurateDepth] +# Midnight Club: LA Remix +ULUS10383 = true +ULES01144 = true +ULJS00180 = true +ULJS00267 = true +ULJM05904 = true +NPJH50440 = true +# Midnight Club 3 : DUB edition +ULUS10021 = true +ULES00108 = true + +# Shadow of Destiny (#9545) +ULUS10459 = true +NPJH50036 = true + +# Burnout games have problems with this on Mali, and have no use for it +# Legends +ULES00125 = true +ULUS10025 = true +ULJM05228 = true +NPJH50305 = true +ULJM05049 = true +ULKS46027 = true +ULAS42019 = true + +# Dominator +ULUS10236 = true +ULES00750 = true +ULJM05242 = true +ULJM05371 = true +NPJH50304 = true +ULES00703 = true +ULAS42095 = true + +[RequireDefaultCPUClock] +# GOW : Ghost of Sparta +UCUS98737 = true +UCAS40323 = true +NPHG00092 = true +NPEG00044 = true +NPEG00045 = true +NPJG00120 = true +NPUG80508 = true +UCJS10114 = true +UCES01401 = true +UCES01473 = true +# GOW : Ghost of Sparta Demo +NPJG90095 = true +NPEG90035 = true +NPUG70125 = true + +[MGS2AcidHack] +ULES00008 = true +ULES00284 = true +ULJM05047 = true +ULKS46065 = true +ULJM08001 = true +ULJM05001 = true +ULAS42007 = true +ULUS10006 = true +ULUS10077 = true + +[SonicRivalsHack] +ULES00622 = true # SR1 +ULUS10195 = true # SR1 +ULUS10323 = true # SR2 +ULES00940 = true # SR2 +ULET00958 = true + +[BlockTransferAllowCreateFB] +NPJH50686 = true # Digimon Adventures (JP, and English patches...) +ULJS00078 = true # MotoGP +ULUS10153 = true # MotoGP +UCES00373 = true # MotoGP +ULUS10551 = true # Ys Seven +ULJM05475 = true # Ys Seven JP +ULUS10549 = true # Ys Seven +NPEH00065 = true # Ys Seven +NPJH50350 = true # Ys Seven +ULJM08041 = true # Ys Seven + +[YugiohSaveFix] +# The cause of Yu-gi-oh series 's bad save (cannot save) are load "save status" and use cwcheat, +# but the real cause still unknown. #7914 + +# Yu-Gi-Oh! Duel Monsters GX: Tag Force +ULJM05151 = true +ULES00600 = true +ULUS10136 = true + +# Yu-Gi-Oh! Duel Monsters GX: Tag Force 2 +ULUS10302 = true +ULJM05260 = true +ULES00925 = true +ULES00926 = true + +# Yu-Gi-Oh! Duel Monsters GX: Tag Force 3 +ULES01183 = true +ULJM05373 = true + +# Yu-Gi-Oh! 5D's Tag Force 4 +ULUS10481 = true +ULJM05479 = true +ULES01362 = true + +# Yu-Gi-Oh! 5D's Tag Force 5 +ULUS10555 = true +ULJM05734 = true +ULES01474 = true + +# Yu-Gi-Oh! 5D's Tag Force 6 +ULJM05940 = true +NPJH50794 = true + +# Yu-Gi-Oh! 5D's Tag Force +ULJM05940 = true + +# Yu-Gi-Oh! ARC-V Tag Force Special +NPJH00142 = true + +[ForceUMDDelay] +# F1 2006 won't boot at all with our standard unrealistically fast timing. +UCES00238 = true +UCJS10045 = true +# F1 2005, japan only? +UCJS10019 = true + +[ForceMax60FPS] +# The GOW games are very heavy and render as fast as they can. They benefit greatly from +# capping the framerate at 60fps. + +UCJS10114 = true +UCKS45084 = true +# GOW : Ghost of Sparta +UCUS98737 = true +UCAS40323 = true +NPHG00092 = true +NPEG00044 = true +NPEG00045 = true +NPJG00120 = true +NPUG80508 = true +UCJS10114 = true +UCES01401 = true +UCES01473 = true +# GOW : Ghost of Sparta Demo +NPEG90035 = true +NPUG70125 = true +NPJG90095 = true +# GOW : Chains Of Olympus +UCAS40198 = true +UCUS98653 = true +UCES00842 = true +ULJM05438 = true +ULJM05348 = true +UCKS45084 = true +NPUG80325 = true +NPEG00023 = true +NPHG00027 = true +NPHG00028 = true +NPJH50170 = true +UCET00844 = true +# GOW: Chains of Olympus Demo +UCUS98705 = true +UCED00971 = true +UCUS98713 = true + +# F1 2006 has extremely long loading times if we don't limit the framerate. +UCES00238 = true +UCJS10045 = true +# F1 2005, japan only? +UCJS10019 = true diff --git a/assets/compat.ini b/assets/compat.ini index 6607fe3a8f..620f55b170 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -368,6 +368,16 @@ ULJS00394 = true ULJS19068 = true NPJH50518 = true # TODO: Will add some games in the future +NPJH50686 = true # Digimon Adventures (JP, and English patches...) +ULJS00078 = true # MotoGP +ULUS10153 = true # MotoGP +UCES00373 = true # MotoGP +ULUS10551 = true # Ys Seven +ULJM05475 = true # Ys Seven JP +ULUS10549 = true # Ys Seven +NPEH00065 = true # Ys Seven +NPJH50350 = true # Ys Seven +ULJM08041 = true # Ys Seven [DisableAccurateDepth] # Midnight Club: LA Remix From d7f40afd9d0229fd0c673f80f1e22bb931dc142f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 Feb 2019 19:02:16 -0800 Subject: [PATCH 02/81] interp: Correct vocp prefix handling. Also, guess that vsocp also applies prefixes. See #5549. --- Core/MIPS/ARM/ArmCompVFPU.cpp | 2 -- Core/MIPS/ARM64/Arm64CompVFPU.cpp | 2 -- Core/MIPS/IR/IRCompVFPU.cpp | 5 +++-- Core/MIPS/MIPSIntVFPU.cpp | 5 ++++- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index 9d2bcfe611..dc17a2be78 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -2302,8 +2302,6 @@ namespace MIPSComp int n = GetNumVectorElements(sz); u8 sregs[4], dregs[4]; - // Actually, not sure that this instruction accepts an S prefix. We don't apply it in the - // interpreter. But whatever. GetVectorRegsPrefixS(sregs, sz, _VS); GetVectorRegsPrefixD(dregs, sz, _VD); diff --git a/Core/MIPS/ARM64/Arm64CompVFPU.cpp b/Core/MIPS/ARM64/Arm64CompVFPU.cpp index 88ba5df94a..a5e6a85fdc 100644 --- a/Core/MIPS/ARM64/Arm64CompVFPU.cpp +++ b/Core/MIPS/ARM64/Arm64CompVFPU.cpp @@ -1953,8 +1953,6 @@ namespace MIPSComp { int n = GetNumVectorElements(sz); u8 sregs[4], dregs[4]; - // Actually, not sure that this instruction accepts an S prefix. We don't apply it in the - // interpreter. But whatever. GetVectorRegsPrefixS(sregs, sz, _VS); GetVectorRegsPrefixD(dregs, sz, _VD); diff --git a/Core/MIPS/IR/IRCompVFPU.cpp b/Core/MIPS/IR/IRCompVFPU.cpp index 0b61953b3c..ef5f3d2282 100644 --- a/Core/MIPS/IR/IRCompVFPU.cpp +++ b/Core/MIPS/IR/IRCompVFPU.cpp @@ -1840,12 +1840,13 @@ namespace MIPSComp { DISABLE; } + // Vector one's complement + // d[N] = 1.0 - s[N] + VectorSize sz = GetVecSize(op); int n = GetNumVectorElements(sz); u8 sregs[4], dregs[4]; - // Actually, not sure that this instruction accepts an S prefix. We don't apply it in the - // interpreter. But whatever. GetVectorRegsPrefixS(sregs, sz, _VS); GetVectorRegsPrefixD(dregs, sz, _VD); diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index 174b211400..b44cb3a922 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -549,6 +549,7 @@ namespace MIPSInt int vs = _VS; VectorSize sz = GetVecSize(op); ReadVector(s, sz, vs); + ApplySwizzleS(s, sz); for (int i = 0; i < GetNumVectorElements(sz); i++) { // Always positive NaN. @@ -567,6 +568,7 @@ namespace MIPSInt int vs = _VS; VectorSize sz = GetVecSize(op); ReadVector(s, sz, vs); + ApplySwizzleS(s, sz); int n = GetNumVectorElements(sz); float x = s[0]; d[0] = nanclamp(1.0f - x, 0.0f, 1.0f); @@ -577,7 +579,8 @@ namespace MIPSInt d[2] = nanclamp(1.0f - y, 0.0f, 1.0f); d[3] = nanclamp(y, 0.0f, 1.0f); outSize = V_Quad; - } + } + ApplyPrefixD(d, sz); WriteVector(d, outSize, vd); PC += 4; EatPrefixes(); From 27d216ea25cf56cec32ec075028316c9167c0d91 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Fri, 22 Feb 2019 06:34:37 +0300 Subject: [PATCH 03/81] Fix postprocessing shader support on macOS Check GL_ARB_shading_language_420pack availability, which SPIRV-Cross assumes present by default, causing explicit binding location generation during shader translation. --- GPU/Common/ShaderTranslation.cpp | 3 +++ ext/native/gfx_es2/gpu_features.cpp | 1 + ext/native/gfx_es2/gpu_features.h | 1 + 3 files changed, 5 insertions(+) diff --git a/GPU/Common/ShaderTranslation.cpp b/GPU/Common/ShaderTranslation.cpp index 862ba286c6..0b5ffa11a5 100644 --- a/GPU/Common/ShaderTranslation.cpp +++ b/GPU/Common/ShaderTranslation.cpp @@ -324,6 +324,9 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShade // Set some options. spirv_cross::CompilerGLSL::Options options; options.version = gl_extensions.GLSLVersion(); + // macOS OpenGL 4.1 implementation does not support GL_ARB_shading_language_420pack. + // Prevent explicit binding location emission enabled in SPIRV-Cross by default. + options.enable_420pack_extension = gl_extensions.ARB_shading_language_420pack; glsl.set_common_options(options); // Compile to GLSL, ready to give to GL driver. *dest = glsl.compile(); diff --git a/ext/native/gfx_es2/gpu_features.cpp b/ext/native/gfx_es2/gpu_features.cpp index 3d81f59287..9dc0bd7b1c 100644 --- a/ext/native/gfx_es2/gpu_features.cpp +++ b/ext/native/gfx_es2/gpu_features.cpp @@ -335,6 +335,7 @@ void CheckGLExtensions() { gl_extensions.EXT_blend_func_extended = g_set_gl_extensions.count("GL_EXT_blend_func_extended") != 0; gl_extensions.ARB_conservative_depth = g_set_gl_extensions.count("GL_ARB_conservative_depth") != 0; gl_extensions.ARB_shader_image_load_store = (g_set_gl_extensions.count("GL_ARB_shader_image_load_store") != 0) || (g_set_gl_extensions.count("GL_EXT_shader_image_load_store") != 0); + gl_extensions.ARB_shading_language_420pack = (g_set_gl_extensions.count("GL_ARB_shading_language_420pack") != 0); gl_extensions.EXT_bgra = g_set_gl_extensions.count("GL_EXT_bgra") != 0; gl_extensions.EXT_gpu_shader4 = g_set_gl_extensions.count("GL_EXT_gpu_shader4") != 0; gl_extensions.NV_framebuffer_blit = g_set_gl_extensions.count("GL_NV_framebuffer_blit") != 0; diff --git a/ext/native/gfx_es2/gpu_features.h b/ext/native/gfx_es2/gpu_features.h index 94ba18912a..95a57f095b 100644 --- a/ext/native/gfx_es2/gpu_features.h +++ b/ext/native/gfx_es2/gpu_features.h @@ -57,6 +57,7 @@ struct GLExtensions { bool ARB_blend_func_extended; // dual source blending bool EXT_blend_func_extended; // dual source blending (GLES, new 2015) bool ARB_shader_image_load_store; + bool ARB_shading_language_420pack; bool ARB_conservative_depth; bool ARB_copy_image; bool ARB_vertex_array_object; From c80dd44da8058b9e1ba0be1997ccdc8fd70d94bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 23 Feb 2019 09:14:40 +0100 Subject: [PATCH 04/81] ARM/ARM64: Ignore invalid immediate addresses in delay slots, which may be conditional. Should do something in x86's safe mem too, but leaving for later. Replaces #11824 --- Core/MIPS/ARM/ArmCompLoadStore.cpp | 13 +++++++++++-- Core/MIPS/ARM64/Arm64CompLoadStore.cpp | 22 ++++++++++++++-------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Core/MIPS/ARM/ArmCompLoadStore.cpp b/Core/MIPS/ARM/ArmCompLoadStore.cpp index bc81e33116..3dfcae2e61 100644 --- a/Core/MIPS/ARM/ArmCompLoadStore.cpp +++ b/Core/MIPS/ARM/ArmCompLoadStore.cpp @@ -179,8 +179,17 @@ namespace MIPSComp return; } - _dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address? CPU bug?"); - load ? gpr.MapDirtyIn(rt, rs, false) : gpr.MapInIn(rt, rs); + // This gets hit in a few games, as a result of never-taken delay slots (some branch types + // conditionally execute the delay slot instructions). Ignore in those cases. + if (!js.inDelaySlot) { + _dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address %08x? CPU bug?", iaddr); + } + + if (load) { + gpr.MapDirtyIn(rt, rs, false); + } else { + gpr.MapInIn(rt, rs); + } if (!g_Config.bFastMemory && rs != MIPS_REG_SP) { SetCCAndR0ForSafeAddress(rs, offset, SCRATCHREG2, true); diff --git a/Core/MIPS/ARM64/Arm64CompLoadStore.cpp b/Core/MIPS/ARM64/Arm64CompLoadStore.cpp index f28074c2e9..e322d4a9a7 100644 --- a/Core/MIPS/ARM64/Arm64CompLoadStore.cpp +++ b/Core/MIPS/ARM64/Arm64CompLoadStore.cpp @@ -172,7 +172,7 @@ namespace MIPSComp { return; } - _dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address? CPU bug?"); + _dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address %08x? CPU bug?", iaddr); if (load) { gpr.MapDirtyIn(rt, rs, false); } else { @@ -364,13 +364,19 @@ namespace MIPSComp { addrReg = SCRATCH1; } } else { - // This actually gets hit in micro machines! rs = ZR rt = ZR. Probably a bug. - // Leaving this a debug assert for future investigation. - _dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address? CPU bug?"); + // This gets hit in a few games, as a result of never-taken delay slots (some branch types + // conditionally execute the delay slot instructions). Ignore in those cases. + if (!js.inDelaySlot) { + _dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address %08x? CPU bug?", iaddr); + } // If we already have a targetReg, we optimized an imm, and rs is already mapped. if (targetReg == INVALID_REG) { - load ? gpr.MapDirtyIn(rt, rs) : gpr.MapInIn(rt, rs); + if (load) { + gpr.MapDirtyIn(rt, rs); + } else { + gpr.MapInIn(rt, rs); + } targetReg = gpr.R(rt); } @@ -413,9 +419,9 @@ namespace MIPSComp { } void Arm64Jit::Comp_Cache(MIPSOpcode op) { -// int imm = (s16)(op & 0xFFFF); -// int rs = _RS; -// int addr = R(rs) + imm; + // int imm = (s16)(op & 0xFFFF); + // int rs = _RS; + // int addr = R(rs) + imm; int func = (op >> 16) & 0x1F; // It appears that a cache line is 0x40 (64) bytes, loops in games From 9b1d10063dd102b61fc57429a658864f1ad896a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 23 Feb 2019 10:46:17 +0100 Subject: [PATCH 05/81] Linux: Draw the graphics API on the splash screen, like most other platforms. --- .gitignore | 1 + UI/MiscScreens.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e391987ab1..89dd7f9292 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ assets/flash0 UWP/icph UWP/.vs .vs +.vscode # For Mac .DS_Store diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 8d7891c08a..e132d44649 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -507,7 +507,7 @@ void LogoScreen::render() { int ppsspp_org_y = yres / 2 + 130; dc.DrawText("www.ppsspp.org", bounds.centerX(), ppsspp_org_y, textColor, ALIGN_CENTER); -#if (defined(_WIN32) && !PPSSPP_PLATFORM(UWP)) || PPSSPP_PLATFORM(ANDROID) +#if (defined(_WIN32) && !PPSSPP_PLATFORM(UWP)) || PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(LINUX) // Draw the graphics API, except on UWP where it's always D3D11 std::string apiName = screenManager()->getDrawContext()->GetInfoString(InfoField::APINAME); dc.DrawText(gr->T(apiName), bounds.centerX(), ppsspp_org_y + 50, textColor, ALIGN_CENTER); From 63f81f96fdf1dfa4f8bee76a809b3864926dd669 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sat, 23 Feb 2019 13:15:23 +0300 Subject: [PATCH 06/81] Disable GLEW on macOS --- ext/glew/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/glew/CMakeLists.txt b/ext/glew/CMakeLists.txt index 60b1c69b08..f147939a92 100644 --- a/ext/glew/CMakeLists.txt +++ b/ext/glew/CMakeLists.txt @@ -1,5 +1,5 @@ find_package(GLEW) -if(GLEW_FOUND) +if(NOT APPLE AND GLEW_FOUND) add_library(system_glew INTERFACE) add_library(Ext::GLEW ALIAS system_glew) target_link_libraries(system_glew INTERFACE GLEW::GLEW) From 24510b818759b0dd8ed3bb1bf4d78a2965c220a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 23 Feb 2019 10:55:28 +0100 Subject: [PATCH 07/81] SDL/Qt: At least quit properly when switching backends --- Qt/QtMain.cpp | 3 +++ SDL/SDLMain.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 32129d42dd..3e18b54028 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -119,6 +119,9 @@ void System_SendMessage(const char *command, const char *parameter) { QCoreApplication::postEvent(emugl, new QEvent((QEvent::Type)browseFileEvent)); } else if (!strcmp(command, "browse_folder")) { QCoreApplication::postEvent(emugl, new QEvent((QEvent::Type)browseFolderEvent)); + } else if (!strcmp(command, "graphics_restart")) { + // Should find a way to properly restart the app. + qApp->exit(0); } } diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 3f07c9fb6a..ae654d4a96 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -116,6 +116,9 @@ void System_SendMessage(const char *command, const char *parameter) { } else if (!strcmp(command, "finish")) { // Do a clean exit g_QuitRequested = true; + } else if (!strcmp(command, "graphics_restart")) { + // Not sure how we best do this, but do a clean exit, better than being stuck in a bad state. + g_QuitRequested = true; } } From d91f7062066136d5a4275444091692df077515dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 23 Feb 2019 10:49:49 +0100 Subject: [PATCH 08/81] Log why the config is being saved (we seem to do it a bit much at times) --- Core/Config.cpp | 8 ++++---- Core/Config.h | 2 +- Qt/QtMain.cpp | 2 +- UI/ComboKeyMappingScreen.cpp | 4 ++-- UI/ControlMappingScreen.cpp | 6 ++---- UI/DisplayLayoutScreen.cpp | 2 +- UI/GameSettingsScreen.cpp | 10 +++++----- UI/MainScreen.cpp | 2 +- UI/NativeApp.cpp | 6 +++--- UI/ReportScreen.cpp | 2 +- UI/TouchControlLayoutScreen.cpp | 2 +- UI/TouchControlVisibilityScreen.cpp | 4 ++-- Windows/EmuThread.cpp | 4 ++-- Windows/GPU/D3D11Context.cpp | 4 ++-- Windows/GPU/WindowsGLContext.cpp | 2 +- Windows/MainWindowMenu.cpp | 8 ++++---- 16 files changed, 33 insertions(+), 35 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index fc2026c9bc..9ae911e268 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1109,7 +1109,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { } } -void Config::Save() { +void Config::Save(const char *saveReason) { if (jitForcedOff) { // if JIT has been forced off, we don't want to screw up the user's ppsspp.ini g_Config.iCpuCore = (int)CPUCore::JIT; @@ -1162,11 +1162,11 @@ void Config::Save() { LogManager::GetInstance()->SaveConfig(log); if (!iniFile.Save(iniFilename_.c_str())) { - ERROR_LOG(LOADER, "Error saving config - can't write ini '%s'", iniFilename_.c_str()); + ERROR_LOG(LOADER, "Error saving config (%s)- can't write ini '%s'", saveReason, iniFilename_.c_str()); System_SendMessage("toast", "Failed to save settings!\nCheck permissions, or try to restart the device."); return; } - INFO_LOG(LOADER, "Config saved: '%s'", iniFilename_.c_str()); + INFO_LOG(LOADER, "Config saved (%s): '%s'", saveReason, iniFilename_.c_str()); if (!bGameSpecific) //otherwise we already did this in saveGameConfig() { @@ -1353,7 +1353,7 @@ bool Config::hasGameConfig(const std::string &pGameId) { } void Config::changeGameSpecific(const std::string &pGameId) { - Save(); + Save("changeGameSpecific"); gameId_ = pGameId; bGameSpecific = !pGameId.empty(); } diff --git a/Core/Config.h b/Core/Config.h index ce8ad14588..a45080ff0e 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -410,7 +410,7 @@ public: std::string dismissedVersion; void Load(const char *iniFileName = nullptr, const char *controllerIniFilename = nullptr); - void Save(); + void Save(const char *saveReason); void RestoreDefaults(); //per game config managment, should maybe be in it's own class diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 3e18b54028..e6e311f0e0 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -405,7 +405,7 @@ bool MainUI::event(QEvent *e) { if (QFile::exists(fileName)) { QDir newPath; g_Config.currentDirectory = newPath.filePath(fileName).toStdString(); - g_Config.Save(); + g_Config.Save("browseFileEvent"); NativeMessageReceived("boot", fileName.toStdString().c_str()); } diff --git a/UI/ComboKeyMappingScreen.cpp b/UI/ComboKeyMappingScreen.cpp index a32d480f76..7860a49710 100644 --- a/UI/ComboKeyMappingScreen.cpp +++ b/UI/ComboKeyMappingScreen.cpp @@ -44,7 +44,7 @@ void Combo_keyScreen::CreateViews() { static const int comboKeyImages[5] = { I_1, I_2, I_3, I_4, I_5, }; - + comboselect = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(10, 10, NONE, NONE)); comboselect->SetSpacing(10); for (int i = 0; i < 5; i++) { @@ -169,7 +169,7 @@ void Combo_keyScreen::onFinish(DialogResult result) { g_Config.iCombokey4 = arrayToInt(array); break; } - g_Config.Save(); + g_Config.Save("Combo_keyScreen::onFInish"); } UI::EventReturn Combo_keyScreen::ChoiceEventHandler::onChoiceClick(UI::EventParams &e){ diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 0612cad540..67cbca1775 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -431,8 +431,8 @@ class JoystickHistoryView : public UI::InertView { public: JoystickHistoryView(int xAxis, int xDevice, int xDir, int yAxis, int yDevice, int yDir, UI::LayoutParams *layoutParams = nullptr) : UI::InertView(layoutParams), - xAxis_(xAxis), xDevice_(xDevice), xDir_(xDir), - yAxis_(yAxis), yDevice_(yDevice), yDir_(yDir), + xAxis_(xAxis), xDir_(xDir), + yAxis_(yAxis), yDir_(yDir), curX_(0.0f), curY_(0.0f), maxCount_(500) {} void Draw(UIContext &dc) override; @@ -455,10 +455,8 @@ private: }; int xAxis_; - int xDevice_; int xDir_; int yAxis_; - int yDevice_; int yDir_; float curX_; diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 0ba1901811..3f5f14ef13 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -173,7 +173,7 @@ void DisplayLayoutScreen::resized() { } void DisplayLayoutScreen::onFinish(DialogResult reason) { - g_Config.Save(); + g_Config.Save("DisplayLayoutScreen::onFinish"); } UI::EventReturn DisplayLayoutScreen::OnCenter(UI::EventParams &e) { diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index c04cc88602..cb1c80fdc1 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -1065,7 +1065,7 @@ void GameSettingsScreen::onFinish(DialogResult result) { Reporting::Enable(enableReports_, "report.ppsspp.org"); Reporting::UpdateConfig(); - g_Config.Save(); + g_Config.Save("GameSettingsScreen::onFinish"); if (editThenRestore_) { g_Config.unloadGameConfig(); } @@ -1137,7 +1137,7 @@ void GameSettingsScreen::CallbackMemstickFolder(bool yes) { writeDataToFile(true, pendingMemstickFolder_.c_str(), pendingMemstickFolder_.size(), memstickDirFile.c_str()); // Save so the settings, at least, are transferred. g_Config.memStickDirectory = pendingMemstickFolder_ + "/"; - g_Config.Save(); + g_Config.Save("MemstickPathChanged"); screenManager()->RecreateAllViews(); } } @@ -1149,7 +1149,7 @@ void GameSettingsScreen::CallbackRenderingBackend(bool yes) { if (yes) { // Extra save here to make sure the choice really gets saved even if there are shutdown bugs in // the GPU backend code. - g_Config.Save(); + g_Config.Save("GameSettingsScreen::RenderingBackendYes"); System_SendMessage("graphics_restart", ""); } else { g_Config.iGPUBackend = (int)GetGPUBackend(); @@ -1162,7 +1162,7 @@ void GameSettingsScreen::CallbackRenderingDevice(bool yes) { if (yes) { // Extra save here to make sure the choice really gets saved even if there are shutdown bugs in // the GPU backend code. - g_Config.Save(); + g_Config.Save("GameSettingsScreen::RenderingDeviceYes"); System_SendMessage("graphics_restart", ""); } else { std::string *deviceNameSetting = GPUDeviceNameSetting(); @@ -1397,7 +1397,7 @@ void DeveloperToolsScreen::CreateViews() { } void DeveloperToolsScreen::onFinish(DialogResult result) { - g_Config.Save(); + g_Config.Save("DeveloperToolsScreen::onFinish"); } void GameSettingsScreen::CallbackRestoreDefaults(bool yes) { diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 8f1fb0044d..46b80d64be 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -1199,7 +1199,7 @@ UI::EventReturn MainScreen::OnExit(UI::EventParams &e) { System_SendMessage("finish", ""); // However, let's make sure the config was saved, since it may not have been. - g_Config.Save(); + g_Config.Save("MainScreen::OnExit"); #ifdef __ANDROID__ #ifdef ANDROID_NDK_PROFILER diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index baa72bb9eb..38e94664e6 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -401,7 +401,7 @@ static void CheckFailedGPUBackends() { writeStringToFile(true, g_Config.sFailedGPUBackends, cache.c_str()); } else { // Just save immediately, since we have storage. - g_Config.Save(); + g_Config.Save("got storage permission"); } } @@ -415,7 +415,7 @@ static void ClearFailedGPUBackends() { if (System_GetPropertyBool(SYSPROP_SUPPORTS_PERMISSIONS)) { File::Delete(GetSysDirectory(DIRECTORY_APP_CACHE) + "/FailedGraphicsBackends.txt"); } else { - g_Config.Save(); + g_Config.Save("clearFailedGPUBackends"); } } @@ -1292,7 +1292,7 @@ void NativeShutdown() { delete host; host = nullptr; #endif - g_Config.Save(); + g_Config.Save("NativeShutdown"); // Avoid shutting this down when restarting core. if (!restarting) diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index ae10ed1660..7901e92a44 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -330,7 +330,7 @@ EventReturn ReportScreen::HandleSubmit(EventParams &e) { if (Reporting::Enable(enableReporting_, "report.ppsspp.org")) { Reporting::UpdateConfig(); - g_Config.Save(); + g_Config.Save("ReportScreen::HandleSubmit"); } std::string filename = includeScreenshot_ ? screenshotFilename_ : ""; diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index 77ca20d956..f75332be81 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -286,7 +286,7 @@ void TouchControlLayoutScreen::resized() { } void TouchControlLayoutScreen::onFinish(DialogResult reason) { - g_Config.Save(); + g_Config.Save("TouchControlLayoutScreen::onFinish"); } UI::EventReturn TouchControlLayoutScreen::OnVisibility(UI::EventParams &e) { diff --git a/UI/TouchControlVisibilityScreen.cpp b/UI/TouchControlVisibilityScreen.cpp index 4e67d1cc5c..20c0407c8b 100644 --- a/UI/TouchControlVisibilityScreen.cpp +++ b/UI/TouchControlVisibilityScreen.cpp @@ -106,14 +106,14 @@ void TouchControlVisibilityScreen::CreateViews() { } choice->SetCentered(true); - + row->Add(choice); grid->Add(row); } } void TouchControlVisibilityScreen::onFinish(DialogResult result) { - g_Config.Save(); + g_Config.Save("TouchControlVisibilityScreen::onFinish"); } UI::EventReturn TouchControlVisibilityScreen::OnToggleAll(UI::EventParams &e) { diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 5a81b5ceb8..3e310bf7cb 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -159,7 +159,7 @@ void MainThreadFunc() { if (performingRestart) { // Okay, switching graphics didn't work out. Probably a driver bug - fallback to restart. // This happens on NVIDIA when switching OpenGL -> Vulkan. - g_Config.Save(); + g_Config.Save("switch_graphics_failed"); W32Util::ExitAndRestart(); } @@ -196,7 +196,7 @@ void MainThreadFunc() { g_Config.iGPUBackend = (int)nextBackend; // Clear this to ensure we try their selection. g_Config.sFailedGPUBackends.clear(); - g_Config.Save(); + g_Config.Save("save_graphics_fallback"); W32Util::ExitAndRestart(); } else { diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index 183a3d0529..2841c00387 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -145,10 +145,10 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { std::wstring title = ConvertUTF8ToWString(err->T("D3D11InitializationError", "Direct3D 11 initialization error")); bool yes = IDYES == MessageBox(hWnd_, error.c_str(), title.c_str(), MB_ICONERROR | MB_YESNO); if (yes) { - // Change the config to D3D and restart. + // Change the config to D3D9 and restart. g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9; g_Config.sFailedGPUBackends.clear(); - g_Config.Save(); + g_Config.Save("save_d3d9_fallback"); W32Util::ExitAndRestart(); } diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index 0701ffa4aa..e4851e6329 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -271,7 +271,7 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) { bool d3d9 = IDYES == MessageBox(hWnd_, whichD3D9.c_str(), title.c_str(), MB_YESNO); g_Config.iGPUBackend = d3d9 ? (int)GPUBackend::DIRECT3D9 : (int)GPUBackend::DIRECT3D11; g_Config.sFailedGPUBackends.clear(); - g_Config.Save(); + g_Config.Save("save_d3d11_fallback"); W32Util::ExitAndRestart(); } diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index b0a87829a7..b6ff2d0eac 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -759,25 +759,25 @@ namespace MainWindow { case ID_OPTIONS_DIRECT3D9: g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9; - g_Config.Save(); + g_Config.Save("gpu_choice"); RestartApp(); break; case ID_OPTIONS_DIRECT3D11: g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11; - g_Config.Save(); + g_Config.Save("gpu_choice"); RestartApp(); break; case ID_OPTIONS_OPENGL: g_Config.iGPUBackend = (int)GPUBackend::OPENGL; - g_Config.Save(); + g_Config.Save("gpu_choice"); RestartApp(); break; case ID_OPTIONS_VULKAN: g_Config.iGPUBackend = (int)GPUBackend::VULKAN; - g_Config.Save(); + g_Config.Save("gpu_choice"); RestartApp(); break; From 2ccd0156f50c9c128bab5b39f8c5a559022df1db Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sat, 23 Feb 2019 14:15:17 +0300 Subject: [PATCH 09/81] Bundle libSDL inside app on macOS, fixes #11830 --- CMakeLists.txt | 3 +++ SDL/macbundle.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100755 SDL/macbundle.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 10fb061423..8ba13db8cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1991,6 +1991,9 @@ if(TargetBin) add_executable(${TargetBin} MACOSX_BUNDLE ${ICON_PATH_ABS} ${NativeAssets} ${SHADER_FILES} ${FLASH0_FILES} ${LANG_FILES} ${NativeAppSource} "ios/Launch Screen.storyboard") else() add_executable(${TargetBin} MACOSX_BUNDLE ${ICON_PATH_ABS} ${NativeAssets} ${SHADER_FILES} ${FLASH0_FILES} ${LANG_FILES} ${NativeAppSource}) + if(TARGET SDL2::SDL2) + add_custom_command(TARGET ${TargetBin} POST_BUILD COMMAND /bin/bash "${CMAKE_SOURCE_DIR}/SDL/macbundle.sh" "${CMAKE_BINARY_DIR}/PPSSPPSDL.app") + endif() endif() elseif(WIN32) add_executable(${TargetBin} WIN32 ${NativeAppSource}) diff --git a/SDL/macbundle.sh b/SDL/macbundle.sh new file mode 100755 index 0000000000..53bf39ce90 --- /dev/null +++ b/SDL/macbundle.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +PPSSPP="${1}" +PPSSPPSDL="${PPSSPP}/Contents/MacOS/PPSSPPSDL" + +if [ ! -f "${PPSSPPSDL}" ]; then + echo "No such file: ${PPSSPPSDL}!" + exit 1 +fi + +SDL=$(otool -L "${PPSSPPSDL}" | grep -v @executable_path | grep -Eo /.+libSDL.+dylib) +if [ "${SDL}" = "" ]; then + echo "SDL is already bundled/unused." + exit 0 +fi + +if [ ! -f "${SDL}" ]; then + echo "Cannot locate SDL: ${SDL}!" + exit 1 +fi + +echo "Installing SDL from ${SDL}..." + +SDLNAME=$(basename "${SDL}") +mkdir -p "${PPSSPP}/Contents/Frameworks" || exit 1 +cp -r "$SDL" "${PPSSPP}/Contents/Frameworks" || exit 1 +install_name_tool -change "${SDL}" "@executable_path/../Frameworks/${SDLNAME}" "${PPSSPPSDL}" || exit 1 From 58c240045e0b720b7adfd5e1d73a53e6edfb8dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 7 Oct 2018 09:54:57 +0200 Subject: [PATCH 10/81] Make window resize work with Vulkan. Seems more stable now. --- SDL/SDLMain.cpp | 2 +- SDL/SDLVulkanGraphicsContext.h | 7 +------ ext/native/thin3d/VulkanRenderManager.cpp | 2 ++ 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index ae654d4a96..7c4ae4074d 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -621,7 +621,7 @@ int main(int argc, char *argv[]) { #if !defined(MOBILE_DEVICE) case SDL_WINDOWEVENT: switch (event.window.event) { - case SDL_WINDOWEVENT_RESIZED: + case SDL_WINDOWEVENT_SIZE_CHANGED: // better than RESIZED, more general { Uint32 window_flags = SDL_GetWindowFlags(window); bool fullscreen = (window_flags & SDL_WINDOW_FULLSCREEN); diff --git a/SDL/SDLVulkanGraphicsContext.h b/SDL/SDLVulkanGraphicsContext.h index 42883b6700..5a29e6c3df 100644 --- a/SDL/SDLVulkanGraphicsContext.h +++ b/SDL/SDLVulkanGraphicsContext.h @@ -25,16 +25,11 @@ public: } void Resize() override { - /* draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); vulkan_->DestroyObjects(); - // TODO: Take from real window dimensions - int width = 1024; - int height = 768; - vulkan_->ReinitSurface(width, height); + vulkan_->ReinitSurface(); vulkan_->InitObjects(); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); - */ } void SwapInterval(int interval) override { diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index dac2b50492..5cd79d4dcb 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -865,7 +865,9 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) { VkResult res = vkAcquireNextImageKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), UINT64_MAX, acquireSemaphore_, (VkFence)VK_NULL_HANDLE, &frameData.curSwapchainImage); if (res == VK_SUBOPTIMAL_KHR) { // Hopefully the resize will happen shortly. Ignore - one frame might look bad or something. + WLOG("VK_SUBOPTIMAL_KHR returned - ignoring"); } else if (res == VK_ERROR_OUT_OF_DATE_KHR) { + WLOG("VK_ERROR_OUT_OF_DATE_KHR returned - not presenting"); frameData.skipSwap = true; } else { _assert_msg_(G3D, res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%s", VulkanResultToString(res)); From 172bcbbf47467384a55061427586142b395763f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 23 Feb 2019 17:17:40 +0100 Subject: [PATCH 11/81] Android: Default screen rotation to auto landscape for new users. Fixes #11832 --- Core/Config.cpp | 2 +- Core/ConfigValues.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 9ae911e268..845d82e081 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -431,7 +431,7 @@ static ConfigSetting generalSettings[] = { ConfigSetting("RemoteDebuggerOnStartup", &g_Config.bRemoteDebuggerOnStartup, false), #ifdef __ANDROID__ - ConfigSetting("ScreenRotation", &g_Config.iScreenRotation, ROTATION_LOCKED_HORIZONTAL), + ConfigSetting("ScreenRotation", &g_Config.iScreenRotation, ROTATION_AUTO_HORIZONTAL), #endif ConfigSetting("InternalScreenRotation", &g_Config.iInternalScreenRotation, ROTATION_LOCKED_HORIZONTAL), diff --git a/Core/ConfigValues.h b/Core/ConfigValues.h index e714fa9b0c..73e5063de3 100644 --- a/Core/ConfigValues.h +++ b/Core/ConfigValues.h @@ -37,6 +37,7 @@ enum { ROTATION_LOCKED_VERTICAL = 2, ROTATION_LOCKED_HORIZONTAL180 = 3, ROTATION_LOCKED_VERTICAL180 = 4, + ROTATION_AUTO_HORIZONTAL = 5, }; enum BufferFilter { From c6c226026d716873a88e29fde7e732fa5443efb7 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Feb 2019 08:40:21 -0800 Subject: [PATCH 12/81] Travis: Remove old clang cache workaround. Now having spaces is causing problems saving the cache. It properly uses other parameters now in the cache key. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 58fd835d41..e227de6e95 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,7 +58,7 @@ matrix: env: PPSSPP_BUILD_TYPE=Android APP_ABI=x86_64 - os: linux - compiler: "clang linux" + compiler: "clang" env: PPSSPP_BUILD_TYPE=Linux - os: linux compiler: "gcc" From 6178a1fb33e7739197d37249285b9723c26eb967 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Feb 2019 09:15:26 -0800 Subject: [PATCH 13/81] Jit: Correct vocp prefix handling. See #5549. Matches tests for various prefix settings. --- Core/MIPS/ARM/ArmCompVFPU.cpp | 15 +++++++++++---- Core/MIPS/ARM/ArmCompVFPUNEON.cpp | 11 ++++++++++- Core/MIPS/ARM64/Arm64CompVFPU.cpp | 14 +++++++++++--- Core/MIPS/IR/IRCompVFPU.cpp | 16 ++++++++++++---- Core/MIPS/MIPSIntVFPU.cpp | 20 ++++++++++++++------ Core/MIPS/x86/CompVFPU.cpp | 28 +++++++++++++++++++++++----- 6 files changed, 81 insertions(+), 23 deletions(-) diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index dc17a2be78..089ace124c 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -2301,8 +2301,16 @@ namespace MIPSComp VectorSize sz = GetVecSize(op); int n = GetNumVectorElements(sz); - u8 sregs[4], dregs[4]; + // This is a hack that modifies prefixes. We eat them later, so just overwrite. + // S prefix forces the negate flags. + js.prefixS |= 0x000F0000; + // T prefix forces constants on and regnum to 1. + // That means negate still works, and abs activates a different constant. + js.prefixT = (js.prefixT & ~0x000000FF) | 0x00000055 | 0x0000F000; + + u8 sregs[4], tregs[4], dregs[4]; GetVectorRegsPrefixS(sregs, sz, _VS); + GetVectorRegsPrefixT(tregs, sz, _VS); GetVectorRegsPrefixD(dregs, sz, _VD); MIPSReg tempregs[4]; @@ -2314,10 +2322,9 @@ namespace MIPSComp } } - MOVI2F(S0, 1.0f, SCRATCHREG1); for (int i = 0; i < n; ++i) { - fpr.MapDirtyInV(tempregs[i], sregs[i]); - VSUB(fpr.V(tempregs[i]), S0, fpr.V(sregs[i])); + fpr.MapDirtyInInV(tempregs[i], sregs[i], tregs[i]); + VADD(fpr.V(tempregs[i]), fpr.V(tregs[i]), fpr.V(sregs[i])); } for (int i = 0; i < n; ++i) { diff --git a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp index 945d993849..1b5ebbe939 100644 --- a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp +++ b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp @@ -1433,12 +1433,21 @@ void ArmJit::CompNEON_Vocp(MIPSOpcode op) { DISABLE; } + // TODO: Handle T prefix. Right now it uses 1.0f always. + + // This is a hack that modifies prefixes. We eat them later, so just overwrite. + // S prefix forces the negate flags. + js.prefixS |= 0x000F0000; + // T prefix forces constants on and regnum to 1. + // That means negate still works, and abs activates a different constant. + js.prefixT = (js.prefixT & ~0x000000FF) | 0x00000055 | 0x0000F000; + VectorSize sz = GetVecSize(op); int n = GetNumVectorElements(sz); MappedRegs regs = NEONMapDirtyIn(op, sz, sz); MOVI2F_neon(Q0, 1.0f, R0); - VSUB(F_32, regs.vd, Q0, regs.vs); + VADD(F_32, regs.vd, Q0, regs.vs); NEONApplyPrefixD(regs.vd); fpr.ReleaseSpillLocksAndDiscardTemps(); diff --git a/Core/MIPS/ARM64/Arm64CompVFPU.cpp b/Core/MIPS/ARM64/Arm64CompVFPU.cpp index a5e6a85fdc..871c7e99ea 100644 --- a/Core/MIPS/ARM64/Arm64CompVFPU.cpp +++ b/Core/MIPS/ARM64/Arm64CompVFPU.cpp @@ -1952,8 +1952,16 @@ namespace MIPSComp { VectorSize sz = GetVecSize(op); int n = GetNumVectorElements(sz); - u8 sregs[4], dregs[4]; + // This is a hack that modifies prefixes. We eat them later, so just overwrite. + // S prefix forces the negate flags. + js.prefixS |= 0x000F0000; + // T prefix forces constants on and regnum to 1. + // That means negate still works, and abs activates a different constant. + js.prefixT = (js.prefixT & ~0x000000FF) | 0x00000055 | 0x0000F000; + + u8 sregs[4], tregs[4], dregs[4]; GetVectorRegsPrefixS(sregs, sz, _VS); + GetVectorRegsPrefixT(tregs, sz, _VS); GetVectorRegsPrefixD(dregs, sz, _VD); MIPSReg tempregs[4]; @@ -1967,8 +1975,8 @@ namespace MIPSComp { fp.MOVI2F(S0, 1.0f, SCRATCH1); for (int i = 0; i < n; ++i) { - fpr.MapDirtyInV(tempregs[i], sregs[i]); - fp.FSUB(fpr.V(tempregs[i]), S0, fpr.V(sregs[i])); + fpr.MapDirtyInInV(tempregs[i], sregs[i], tregs[i]); + fp.FADD(fpr.V(tempregs[i]), fpr.V(tregs[i]), fpr.V(sregs[i])); } for (int i = 0; i < n; ++i) { diff --git a/Core/MIPS/IR/IRCompVFPU.cpp b/Core/MIPS/IR/IRCompVFPU.cpp index ef5f3d2282..f3019f9f50 100644 --- a/Core/MIPS/IR/IRCompVFPU.cpp +++ b/Core/MIPS/IR/IRCompVFPU.cpp @@ -1846,22 +1846,30 @@ namespace MIPSComp { VectorSize sz = GetVecSize(op); int n = GetNumVectorElements(sz); - u8 sregs[4], dregs[4]; + // This is a hack that modifies prefixes. We eat them later, so just overwrite. + // S prefix forces the negate flags. + js.prefixS |= 0x000F0000; + // T prefix forces constants on and regnum to 1. + // That means negate still works, and abs activates a different constant. + js.prefixT = (js.prefixT & ~0x000000FF) | 0x00000055 | 0x0000F000; + + u8 sregs[4], tregs[4], dregs[4]; GetVectorRegsPrefixS(sregs, sz, _VS); + // There's no bits for t, so just reuse s. It'll be constants only. + GetVectorRegsPrefixT(tregs, sz, _VS); GetVectorRegsPrefixD(dregs, sz, _VD); u8 tempregs[4]; for (int i = 0; i < n; ++i) { if (!IsOverlapSafe(dregs[i], n, sregs)) { - tempregs[i] = IRVTEMP_PFX_T + i; // using IRTEMP0 for other things + tempregs[i] = IRVTEMP_0 + i; } else { tempregs[i] = dregs[i]; } } - ir.Write(IROp::SetConstF, IRVTEMP_0, ir.AddConstantFloat(1.0f)); for (int i = 0; i < n; ++i) { - ir.Write(IROp::FSub, tempregs[i], IRVTEMP_0, sregs[i]); + ir.Write(IROp::FAdd, tempregs[i], tregs[i], sregs[i]); } for (int i = 0; i < n; ++i) { if (dregs[i] != tempregs[i]) { diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index b44cb3a922..30ded3b737 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -544,16 +544,24 @@ namespace MIPSInt void Int_Vocp(MIPSOpcode op) { - float s[4], d[4]; + float s[4], t[4], d[4]; int vd = _VD; int vs = _VS; VectorSize sz = GetVecSize(op); ReadVector(s, sz, vs); - ApplySwizzleS(s, sz); - for (int i = 0; i < GetNumVectorElements(sz); i++) - { - // Always positive NaN. - d[i] = my_isnan(s[i]) ? fabsf(s[i]) : 1.0f - s[i]; + + // S prefix forces the negate flags. + u32 sprefix = currentMIPS->vfpuCtrl[VFPU_CTRL_SPREFIX]; + ApplyPrefixST(s, sprefix | 0x000F0000, sz); + + // T prefix forces constants on and regnum to 1. + // That means negate still works, and abs activates a different constant. + u32 tprefix = currentMIPS->vfpuCtrl[VFPU_CTRL_TPREFIX]; + ApplyPrefixST(t, (tprefix & ~0x000000FF) | 0x00000055 | 0x0000F000, sz); + + for (int i = 0; i < GetNumVectorElements(sz); i++) { + // Always positive NaN. Note that s is always negated from the registers. + d[i] = my_isnan(s[i]) ? fabsf(s[i]) : t[i] + s[i]; } ApplyPrefixD(d, sz); WriteVector(d, sz, vd); diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index d74a1f8e3a..10a1e6e9bc 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -2026,12 +2026,24 @@ void Jit::Comp_Vocp(MIPSOpcode op) { VectorSize sz = GetVecSize(op); int n = GetNumVectorElements(sz); - u8 sregs[4], dregs[4]; + // This is a hack that modifies prefixes. We eat them later, so just overwrite. + // S prefix forces the negate flags. + js.prefixS |= 0x000F0000; + // T prefix forces constants on and regnum to 1. + // That means negate still works, and abs activates a different constant. + js.prefixT = (js.prefixT & ~0x000000FF) | 0x00000055 | 0x0000F000; + + u8 sregs[4], tregs[4], dregs[4]; + // Actually uses the T prefixes (despite being VS.) GetVectorRegsPrefixS(sregs, sz, _VS); + if (js.prefixT != 0x0000F055) + GetVectorRegsPrefixT(tregs, sz, _VS); GetVectorRegsPrefixD(dregs, sz, _VD); // Flush SIMD. fpr.SimpleRegsV(sregs, sz, 0); + if (js.prefixT != 0x0000F055) + fpr.SimpleRegsV(tregs, sz, 0); fpr.SimpleRegsV(dregs, sz, MAP_NOINIT | MAP_DIRTY); X64Reg tempxregs[4]; @@ -2048,11 +2060,17 @@ void Jit::Comp_Vocp(MIPSOpcode op) { } } - MOV(PTRBITS, R(TEMPREG), ImmPtr(&one)); - MOVSS(XMM1, MatR(TEMPREG)); + if (js.prefixT == 0x0000F055) { + MOV(PTRBITS, R(TEMPREG), ImmPtr(&one)); + MOVSS(XMM1, MatR(TEMPREG)); + } for (int i = 0; i < n; ++i) { - MOVSS(XMM0, R(XMM1)); - SUBSS(XMM0, fpr.V(sregs[i])); + if (js.prefixT == 0x0000F055) { + MOVSS(XMM0, R(XMM1)); + } else { + MOVSS(XMM0, fpr.V(tregs[i])); + } + ADDSS(XMM0, fpr.V(sregs[i])); MOVSS(tempxregs[i], R(XMM0)); } From 179ec618158c09b371dcd84a480883874bc75e6c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Feb 2019 10:05:13 -0800 Subject: [PATCH 14/81] interp: Correctly handle vsocp prefixes. Very similar to vsop, just with a bit more fixed values. --- Core/MIPS/MIPSIntVFPU.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index 30ded3b737..8d562cfd8d 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -571,22 +571,30 @@ namespace MIPSInt void Int_Vsocp(MIPSOpcode op) { - float s[4], d[4]; + float s[4], t[4], d[4]; int vd = _VD; int vs = _VS; VectorSize sz = GetVecSize(op); + VectorSize outSize = GetDoubleVectorSize(sz); ReadVector(s, sz, vs); - ApplySwizzleS(s, sz); + + // S prefix forces negate in even/odd and xxyy swizzle. + // abs works, and applies to final position (not source.) + u32 sprefix = currentMIPS->vfpuCtrl[VFPU_CTRL_SPREFIX]; + ApplyPrefixST(s, (sprefix & ~0x000F00FF) | 0x00000050 | 0x00050000, outSize); + + // T prefix forces constants on and regnum to 0, 1, 0, 1. + // That means negate still works, and abs activates a different constant. + u32 tprefix = currentMIPS->vfpuCtrl[VFPU_CTRL_TPREFIX]; + ApplyPrefixST(t, (tprefix & ~0x000000FF) | 0x00000011 | 0x0000F000, outSize); + int n = GetNumVectorElements(sz); - float x = s[0]; - d[0] = nanclamp(1.0f - x, 0.0f, 1.0f); - d[1] = nanclamp(x, 0.0f, 1.0f); - VectorSize outSize = V_Pair; - if (n > 1) { - float y = s[1]; - d[2] = nanclamp(1.0f - y, 0.0f, 1.0f); - d[3] = nanclamp(y, 0.0f, 1.0f); - outSize = V_Quad; + // Essentially D prefix saturation is forced. + d[0] = nanclamp(t[0] + s[0], 0.0f, 1.0f); + d[1] = nanclamp(t[1] + s[1], 0.0f, 1.0f); + if (outSize == V_Quad) { + d[2] = nanclamp(t[2] + s[2], 0.0f, 1.0f); + d[3] = nanclamp(t[3] + s[3], 0.0f, 1.0f); } ApplyPrefixD(d, sz); WriteVector(d, outSize, vd); From 520f850e09f64541f86783a9ecf0ff4b70f8950f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Feb 2019 13:49:56 -0800 Subject: [PATCH 15/81] Jit: Correct VFPU prefix eating flags. Verified by tests. Also, confirmed that the old vxbz encoding had no output, but the new position (as used by gas) does. --- Core/MIPS/MIPSTables.cpp | 47 +++++++++++++++------------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 3dffeea518..4b537afaf1 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -524,8 +524,7 @@ const MIPSInstruction tableVFPU0[8] = // 011000 xxx ....... . ....... . ....... { INSTR("vadd", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INSTR("vsub", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), - // TODO: Flags may not be correct (prefixes, etc.) - INSTR("vsbn", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vsbn, IN_OTHER|OUT_OTHER|IS_VFPU), + INSTR("vsbn", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vsbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INVALID, INVALID, INVALID, INVALID, INSTR("vdiv", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), @@ -577,20 +576,18 @@ const MIPSInstruction tableVFPU4Jump[32] = // 110100 xxxxx ..... . ....... . ... INVALID, INVALID, //24 - 110100 11 ........ . ....... . ....... - // TODO: Flags may not be correct (prefixes, etc.) - INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU), - INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU), - INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU), - INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU), - INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU), - INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU), - INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU), - INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU), + INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vwbn.s", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), }; const MIPSInstruction tableVFPU7[32] = // 110100 00001 xxxxx . ....... . ....... { - // TODO disasm INSTR("vrnds", JITFUNC(Comp_Generic), Dis_Vrnds, Int_Vrnds, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INSTR("vrndi", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INSTR("vrndf1", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), @@ -599,9 +596,7 @@ const MIPSInstruction tableVFPU7[32] = // 110100 00001 xxxxx . ....... . ....... INVALID, INVALID, INVALID, INVALID, //8 INVALID, INVALID, INVALID, INVALID, - // TODO: Flags may not be correct (prefixes, etc.) Is this the correct encoding? Others say 10110. - INSTR("vsbz", JITFUNC(Comp_Generic), Dis_Generic, Int_Vsbz, IN_OTHER|OUT_OTHER|IS_VFPU), - INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, //16 INVALID, INVALID, @@ -610,9 +605,8 @@ const MIPSInstruction tableVFPU7[32] = // 110100 00001 xxxxx . ....... . ....... INVALID, INVALID, - INVALID, - // TODO: Flags may not be correct (prefixes, etc.) - INSTR("vlgb", JITFUNC(Comp_Generic), Dis_Generic, Int_Vlgb, IN_OTHER|OUT_OTHER|IS_VFPU), + INSTR("vsbz", JITFUNC(Comp_Generic), Dis_Generic, Int_Vsbz, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vlgb", JITFUNC(Comp_Generic), Dis_Generic, Int_Vlgb, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), //24 INSTR("vuc2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), // Seen in BraveStory, initialization 110100 00001110000 000 0001 0000 0000 INSTR("vc2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), @@ -731,23 +725,18 @@ const MIPSInstruction tableVFPUMatrixSet1[16] = // 111100 11100 .xxxx . ....... const MIPSInstruction tableVFPU9[32] = // 110100 00010 xxxxx . ....... . ....... { - // TODO: Flags may not be correct (prefixes, etc.) - INSTR("vsrt1", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt1, IN_OTHER|OUT_OTHER|IS_VFPU), - // TODO: Flags may not be correct (prefixes, etc.) - INSTR("vsrt2", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt2, IN_OTHER|OUT_OTHER|IS_VFPU), + INSTR("vsrt1", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt1, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vsrt2", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt2, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INSTR("vbfy1", JITFUNC(Comp_Vbfy), Dis_Vbfy, Int_Vbfy, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INSTR("vbfy2", JITFUNC(Comp_Vbfy), Dis_Vbfy, Int_Vbfy, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), //4 INSTR("vocp", JITFUNC(Comp_Vocp), Dis_Vbfy, Int_Vocp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), // one's complement INSTR("vsocp", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsocp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INSTR("vfad", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vfad, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), - // TODO: Flags may not be correct (prefixes, etc.) - INSTR("vavg", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vavg, IN_OTHER|OUT_OTHER|IS_VFPU), + INSTR("vavg", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vavg, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), //8 - // TODO: Flags may not be correct (prefixes, etc.) - INSTR("vsrt3", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt3, IN_OTHER|OUT_OTHER|IS_VFPU), - // TODO: Flags may not be correct (prefixes, etc.) - INSTR("vsrt4", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt4, IN_OTHER|OUT_OTHER|IS_VFPU), + INSTR("vsrt3", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vsrt4", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt4, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INSTR("vsgn", JITFUNC(Comp_Vsgn), Dis_Vbfy, Int_Vsgn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INVALID, //12 @@ -757,9 +746,7 @@ const MIPSInstruction tableVFPU9[32] = // 110100 00010 xxxxx . ....... . ....... INVALID, //16 - // TODO: Flags may not be correct (prefixes, etc.) INSTR("vmfvc", JITFUNC(Comp_Vmfvc), Dis_Vmftvc, Int_Vmfvc, IN_OTHER|IN_VFPU_CC|OUT_OTHER|IS_VFPU), - // TODO: Flags may not be correct (prefixes, etc.) INSTR("vmtvc", JITFUNC(Comp_Vmtvc), Dis_Vmftvc, Int_Vmtvc, IN_OTHER|OUT_VFPU_CC|OUT_OTHER|IS_VFPU), INVALID, INVALID, From aff1d8e8b220de2ed548769dbf4a6f03714bf573 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Feb 2019 15:04:54 -0800 Subject: [PATCH 16/81] interp: Implement vsbz and vlgb. Not sure any games actually use them, but good to have the remaining vfpu ops all implemented. --- Core/MIPS/MIPSIntVFPU.cpp | 57 ++++++++++++++++++++++++++++++++++----- Core/MIPS/MIPSTables.cpp | 1 + 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index 8d562cfd8d..012579299e 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -1820,11 +1820,33 @@ bad: void Int_Vlgb(MIPSOpcode op) { - // S & D valid - Reporting::ReportMessage("vlgb not implemented"); - if (!PSP_CoreParameter().headLess) { - _dbg_assert_msg_(CPU,0,"vlgb not implemented"); + // Vector log binary (extract exponent) + int vd = _VD; + int vs = _VS; + VectorSize sz = GetVecSize(op); + + FloatBits d; + FloatBits s; + + ReadVector(s.f, sz, vs); + // TODO: Test swizzle, t? + ApplySwizzleS(s.f, sz); + + if (sz != V_Single) { + ERROR_LOG_REPORT(CPU, "vlgb not implemented for size %d", GetNumVectorElements(sz)); } + for (int i = 0; i < GetNumVectorElements(sz); ++i) { + int exp = (s.u[i] & 0x7F800000) >> 23; + if (exp == 0xFF) { + d.f[i] = s.f[i]; + } else if (exp == 0) { + d.f[i] = -INFINITY; + } else { + d.f[i] = (float)(exp - 127); + } + } + ApplyPrefixD(d.f, sz); + WriteVector(d.f, sz, vd); PC += 4; EatPrefixes(); } @@ -1905,10 +1927,31 @@ bad: void Int_Vsbz(MIPSOpcode op) { - Reporting::ReportMessage("vsbz not implemented"); - if (!PSP_CoreParameter().headLess) { - _dbg_assert_msg_(CPU,0,"vsbz not implemented"); + // Vector scale by zero (set exp to 0 to extract mantissa) + int vd = _VD; + int vs = _VS; + VectorSize sz = GetVecSize(op); + + FloatBits d; + FloatBits s; + + ReadVector(s.f, sz, vs); + // TODO: Test swizzle, t? + ApplySwizzleS(s.f, sz); + + if (sz != V_Single) { + ERROR_LOG_REPORT(CPU, "vsbz not implemented for size %d", GetNumVectorElements(sz)); } + for (int i = 0; i < GetNumVectorElements(sz); ++i) { + // NAN and denormals pass through. + if (my_isnan(s.f[i]) || (s.u[i] & 0x7F800000) == 0) { + d.u[i] = s.u[i]; + } else { + d.u[i] = (127 << 23) | (s.u[i] & 0x007FFFFF); + } + } + ApplyPrefixD(d.f, sz); + WriteVector(d.f, sz, vd); PC += 4; EatPrefixes(); } diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 4b537afaf1..69e5d28afa 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -524,6 +524,7 @@ const MIPSInstruction tableVFPU0[8] = // 011000 xxx ....... . ....... . ....... { INSTR("vadd", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INSTR("vsub", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + // TODO: Disasm is wrong. INSTR("vsbn", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vsbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INVALID, INVALID, INVALID, INVALID, From c1427f598164627a345a04827fe8a2d45bac191c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Feb 2019 22:22:51 +0100 Subject: [PATCH 17/81] VulkanImage: Fix issue where we'd try to free dedicated allocations from the allocator_ instead of Vulkan directly. Snuck in some minor cleanups. --- Common/Vulkan/VulkanImage.cpp | 18 +++++++++++------- Common/Vulkan/VulkanImage.h | 8 ++++---- GPU/Vulkan/DepalettizeShaderVulkan.cpp | 16 +++++++++------- GPU/Vulkan/DrawEngineVulkan.h | 2 +- GPU/Vulkan/FramebufferVulkan.cpp | 4 ++-- GPU/Vulkan/TextureCacheVulkan.cpp | 8 ++++---- ext/native/thin3d/thin3d_vulkan.cpp | 8 ++++---- 7 files changed, 35 insertions(+), 29 deletions(-) diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/Vulkan/VulkanImage.cpp index 4c4d2fcff1..5c5e513948 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/Vulkan/VulkanImage.cpp @@ -30,7 +30,7 @@ static bool IsDepthStencilFormat(VkFormat format) { } } -bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage, const VkComponentMapping *mapping) { +bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *allocator, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage, const VkComponentMapping *mapping) { Wipe(); width_ = w; @@ -75,7 +75,8 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, bool dedicatedAllocation = false; vulkan_->GetImageMemoryRequirements(image_, &mem_reqs, &dedicatedAllocation); - if (allocator_ && !dedicatedAllocation) { + if (allocator && !dedicatedAllocation) { + allocator_ = allocator; offset_ = allocator_->Allocate(mem_reqs, &mem_, Tag()); if (offset_ == VulkanDeviceAllocator::ALLOCATE_FAILED) { ELOG("Image memory allocation failed (mem_reqs.size=%d, typebits=%08x", (int)mem_reqs.size, (int)mem_reqs.memoryTypeBits); @@ -231,10 +232,13 @@ void VulkanTexture::Destroy() { if (image_ != VK_NULL_HANDLE) { vulkan_->Delete().QueueDeleteImage(image_); } - if (mem_ != VK_NULL_HANDLE && !allocator_) { - vulkan_->Delete().QueueDeleteDeviceMemory(mem_); - } else if (mem_ != VK_NULL_HANDLE) { - allocator_->Free(mem_, offset_); - mem_ = VK_NULL_HANDLE; + if (mem_ != VK_NULL_HANDLE) { + if (allocator_) { + allocator_->Free(mem_, offset_); + mem_ = VK_NULL_HANDLE; + allocator_ = nullptr; + } else { + vulkan_->Delete().QueueDeleteDeviceMemory(mem_); + } } } diff --git a/Common/Vulkan/VulkanImage.h b/Common/Vulkan/VulkanImage.h index 9a23d91784..64f84a8997 100644 --- a/Common/Vulkan/VulkanImage.h +++ b/Common/Vulkan/VulkanImage.h @@ -8,8 +8,8 @@ class VulkanDeviceAllocator; // Not very optimal - if you have many small textures you should use other strategies. class VulkanTexture { public: - VulkanTexture(VulkanContext *vulkan, VulkanDeviceAllocator *allocator) - : vulkan_(vulkan), allocator_(allocator) { + VulkanTexture(VulkanContext *vulkan) + : vulkan_(vulkan) { } ~VulkanTexture() { Destroy(); @@ -18,7 +18,7 @@ public: // Fast uploads from buffer. Mipmaps supported. // Usage must at least include VK_IMAGE_USAGE_TRANSFER_DST_BIT in order to use UploadMip. // When using UploadMip, initialLayout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL. - bool CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, const VkComponentMapping *mapping = nullptr); + bool CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *allocator, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, const VkComponentMapping *mapping = nullptr); void UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mipHeight, VkBuffer buffer, uint32_t offset, size_t rowLength); // rowLength is in pixels void GenerateMip(VkCommandBuffer cmd, int mip); void EndCreate(VkCommandBuffer cmd, bool vertexTexture = false); @@ -55,7 +55,7 @@ private: int32_t height_ = 0; int32_t numMips_ = 1; VkFormat format_ = VK_FORMAT_UNDEFINED; - VulkanDeviceAllocator *allocator_; + VulkanDeviceAllocator *allocator_ = nullptr; // If set, memory is from this allocator. size_t offset_ = 0; std::string tag_; }; diff --git a/GPU/Vulkan/DepalettizeShaderVulkan.cpp b/GPU/Vulkan/DepalettizeShaderVulkan.cpp index 57e61fef65..b759882ad7 100644 --- a/GPU/Vulkan/DepalettizeShaderVulkan.cpp +++ b/GPU/Vulkan/DepalettizeShaderVulkan.cpp @@ -129,16 +129,18 @@ VulkanTexture *DepalShaderCacheVulkan::GetClutTexture(GEPaletteFormat clutFormat VkFormat destFormat = GetClutDestFormat(clutFormat, &componentMapping); int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512; + VulkanTexture *vktex = new VulkanTexture(vulkan_); + vktex->SetTag("DepalClut"); + VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER); + if (!vktex->CreateDirect(cmd, alloc_, texturePixels, 1, 1, destFormat, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, &componentMapping)) { + ERROR_LOG(G3D, "Failed to create texture for CLUT"); + return nullptr; + } + VkBuffer pushBuffer; uint32_t pushOffset = push_->PushAligned(rawClut, 1024, 4, &pushBuffer); - VulkanTexture *vktex = new VulkanTexture(vulkan_, alloc_); - vktex->SetTag("DepalClut"); - VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER); - if (!vktex->CreateDirect(cmd, texturePixels, 1, 1, destFormat, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, &componentMapping)) { - Crash(); - } vktex->UploadMip(cmd, 0, texturePixels, 1, pushBuffer, pushOffset, texturePixels); vktex->EndCreate(cmd); diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index cece2c08c6..9065c94611 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -194,7 +194,7 @@ public: void SetLineWidth(float lineWidth); void SetDepalTexture(VkImageView depal) { - if (boundDepal_ != depal) { + if (boundDepal_ != depal && depal) { boundDepal_ = depal; gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); } diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index 2e87b65390..3282a812b9 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -195,9 +195,9 @@ void FramebufferManagerVulkan::MakePixelTexture(const u8 *srcPixels, GEBufferFor VkCommandBuffer initCmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER); // There's only ever a few of these alive, don't need to stress the allocator with these big ones. - drawPixelsTex_ = new VulkanTexture(vulkan_, nullptr); + drawPixelsTex_ = new VulkanTexture(vulkan_); drawPixelsTex_->SetTag("DrawPixels"); - if (!drawPixelsTex_->CreateDirect(initCmd, width, height, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)) { + if (!drawPixelsTex_->CreateDirect(initCmd, nullptr, width, height, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)) { // out of memory? delete drawPixelsTex_; drawPixelsTex_ = nullptr; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 0eb056af6c..d092893d40 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -351,7 +351,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr depalShaderCache_->SetPushBuffer(drawEngine_->GetPushBufferForTextureData()); const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); VulkanTexture *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_); - drawEngine_->SetDepalTexture(clutTexture->GetImageView()); + drawEngine_->SetDepalTexture(clutTexture ? clutTexture->GetImageView() : VK_NULL_HANDLE); // Only point filtering enabled. samplerKey.magFilt = false; samplerKey.minFilt = false; @@ -599,7 +599,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { { delete entry->vkTex; - entry->vkTex = new VulkanTexture(vulkan_, allocator_); + entry->vkTex = new VulkanTexture(vulkan_); VulkanTexture *image = entry->vkTex; const VkComponentMapping *mapping; @@ -625,7 +625,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { snprintf(texName, sizeof(texName), "Texture%08x", entry->addr); image->SetTag(texName); - bool allocSuccess = image->CreateDirect(cmdInit, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping); + bool allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping); if (!allocSuccess && !lowMemoryMode_) { WARN_LOG_REPORT(G3D, "Texture cache ran out of GPU memory; switching to low memory mode"); lowMemoryMode_ = true; @@ -644,7 +644,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { scaleFactor = 1; actualFmt = dstFmt; - allocSuccess = image->CreateDirect(cmdInit, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping); + allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping); } if (!allocSuccess) { diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 1ff74d1d5a..17dda0da30 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -630,11 +630,11 @@ static inline VkSamplerAddressMode AddressModeToVulkan(Draw::TextureAddressMode VulkanTexture *VKContext::GetNullTexture() { if (!nullTexture_) { VkCommandBuffer cmdInit = renderManager_.GetInitCmd(); - nullTexture_ = new VulkanTexture(vulkan_, allocator_); + nullTexture_ = new VulkanTexture(vulkan_); nullTexture_->SetTag("Null"); int w = 8; int h = 8; - nullTexture_->CreateDirect(cmdInit, w, h, 1, VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + nullTexture_->CreateDirect(cmdInit, allocator_, w, h, 1, VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); uint32_t bindOffset; VkBuffer bindBuf; @@ -713,7 +713,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur width_ = desc.width; height_ = desc.height; depth_ = desc.depth; - vkTex_ = new VulkanTexture(vulkan_, alloc); + vkTex_ = new VulkanTexture(vulkan_); vkTex_->SetTag(desc.tag); VkFormat vulkanFormat = DataFormatToVulkan(format_); int bpp = GetBpp(vulkanFormat); @@ -723,7 +723,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur // Gonna have to generate some, which requires TRANSFER_SRC usageBits |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; } - if (!vkTex_->CreateDirect(cmd, width_, height_, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits)) { + if (!vkTex_->CreateDirect(cmd, alloc, width_, height_, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits)) { ELOG("Failed to create VulkanTexture: %dx%dx%d fmt %d, %d levels", width_, height_, depth_, (int)vulkanFormat, mipLevels_); return false; } From bf2bbd891ce382a386c7970301b130e36bf8b91d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 25 Feb 2019 15:15:04 +0100 Subject: [PATCH 18/81] Back out wrong change. Leaving better error handling for later. --- GPU/Vulkan/DrawEngineVulkan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 9065c94611..cece2c08c6 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -194,7 +194,7 @@ public: void SetLineWidth(float lineWidth); void SetDepalTexture(VkImageView depal) { - if (boundDepal_ != depal && depal) { + if (boundDepal_ != depal) { boundDepal_ = depal; gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); } From e3d7ca67a030e9b9c04351d045f7c174636092e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 25 Feb 2019 15:50:07 +0100 Subject: [PATCH 19/81] Rename the lag sync config ini setting to reset it for all users. See #10195. --- Core/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 845d82e081..f1805dab3b 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -396,7 +396,7 @@ static ConfigSetting generalSettings[] = { ConfigSetting("ShowDebuggerOnLoad", &g_Config.bShowDebuggerOnLoad, false), ConfigSetting("CheckForNewVersion", &g_Config.bCheckForNewVersion, true), ConfigSetting("Language", &g_Config.sLanguageIni, &DefaultLangRegion), - ConfigSetting("ForceLagSync", &g_Config.bForceLagSync, false, true, true), + ConfigSetting("ForceLagSync2", &g_Config.bForceLagSync, false, true, true), ConfigSetting("DiscordPresence", &g_Config.bDiscordPresence, true, true, false), // Or maybe it makes sense to have it per-game? Race conditions abound... ReportedConfigSetting("NumWorkerThreads", &g_Config.iNumWorkerThreads, &DefaultNumWorkers, true, true), From 0cd3ac06d06ffad0af505903cbef2378d3197573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 25 Feb 2019 20:51:19 +0100 Subject: [PATCH 20/81] Avoid trying to create a FileLoader for empty filenames Assorted cleanup --- Core/FileLoaders/LocalFileLoader.cpp | 17 +++++++++++------ Core/FileSystems/DirectoryFileSystem.cpp | 10 +++++----- UI/GameInfoCache.cpp | 5 +++++ UI/GameInfoCache.h | 1 + Windows/GPU/WindowsVulkanContext.cpp | 2 +- ext/native/file/path.h | 2 +- 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/Core/FileLoaders/LocalFileLoader.cpp b/Core/FileLoaders/LocalFileLoader.cpp index a537ee0211..c373e4dac6 100644 --- a/Core/FileLoaders/LocalFileLoader.cpp +++ b/Core/FileLoaders/LocalFileLoader.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include + #include "ppsspp_config.h" #include "util/text/utf8.h" #include "file/file_util.h" @@ -30,7 +31,10 @@ LocalFileLoader::LocalFileLoader(const std::string &filename) : filesize_(0), filename_(filename) { - + if (filename.empty()) { + ERROR_LOG(FILESYS, "LocalFileLoader can't load empty filenames"); + return; + } #ifndef _WIN32 fd_ = open(filename.c_str(), O_RDONLY | O_CLOEXEC); @@ -47,7 +51,7 @@ LocalFileLoader::LocalFileLoader(const std::string &filename) lseek(fd_, 0, SEEK_SET); #endif -#else // !_WIN32 +#else // _WIN32 const DWORD access = GENERIC_READ, share = FILE_SHARE_READ, mode = OPEN_EXISTING, flags = FILE_ATTRIBUTE_NORMAL; #if PPSSPP_PLATFORM(UWP) @@ -60,14 +64,15 @@ LocalFileLoader::LocalFileLoader(const std::string &filename) } LARGE_INTEGER end_offset; const LARGE_INTEGER zero = { 0 }; - if(SetFilePointerEx(handle_, zero, &end_offset, FILE_END) == 0) { + if (SetFilePointerEx(handle_, zero, &end_offset, FILE_END) == 0) { + // Couldn't seek in the file. Close it and give up? This should never happen. + CloseHandle(handle_); + handle_ = INVALID_HANDLE_VALUE; return; } filesize_ = end_offset.QuadPart; SetFilePointerEx(handle_, zero, nullptr, FILE_BEGIN); - -#endif // !_WIN32 - +#endif // _WIN32 } LocalFileLoader::~LocalFileLoader() { diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 40810d1fae..cb7cffd1c7 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -154,6 +154,10 @@ DirectoryFileSystem::DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string hAlloc = _hAlloc; } +DirectoryFileSystem::~DirectoryFileSystem() { + CloseAll(); +} + std::string DirectoryFileHandle::GetLocalPath(std::string& basePath, std::string localpath) { if (localpath.empty()) @@ -445,16 +449,12 @@ void DirectoryFileHandle::Close() void DirectoryFileSystem::CloseAll() { for (auto iter = entries.begin(); iter != entries.end(); ++iter) { + INFO_LOG(FILESYS, "DirectoryFileSystem::CloseAll(): Force closing %d (%s)", (int)iter->first, iter->second.guestFilename.c_str()); iter->second.hFile.Close(); } - entries.clear(); } -DirectoryFileSystem::~DirectoryFileSystem() { - CloseAll(); -} - std::string DirectoryFileSystem::GetLocalPath(std::string localpath) { if (localpath.empty()) return basePath; diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index c1f263c71f..05558dd2b9 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -229,6 +229,11 @@ bool GameInfo::LoadFromPath(const std::string &gamePath) { } std::shared_ptr GameInfo::GetFileLoader() { + if (filePath_.empty()) { + // Happens when workqueue tries to figure out priorities in PrioritizedWorkQueue::Pop(), + // because priority() calls GetFileLoader()... gnarly. + return fileLoader; + } if (!fileLoader) { fileLoader.reset(ConstructFileLoader(filePath_)); } diff --git a/UI/GameInfoCache.h b/UI/GameInfoCache.h index ccad4ba683..90419444fd 100644 --- a/UI/GameInfoCache.h +++ b/UI/GameInfoCache.h @@ -146,6 +146,7 @@ protected: // Note: this can change while loading, use GetTitle(). std::string title; + // TODO: Get rid of this shared_ptr and managae lifetime better instead. std::shared_ptr fileLoader; std::string filePath_; diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index fbbf1ce12d..aa99f66190 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -128,8 +128,8 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m int bits = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT - | VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + // We're intentionally skipping VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT g_Vulkan->InitDebugUtilsCallback(&VulkanDebugUtilsCallback, bits, &g_LogOptions); } else { int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; diff --git a/ext/native/file/path.h b/ext/native/file/path.h index 42a291b032..b54e9be494 100644 --- a/ext/native/file/path.h +++ b/ext/native/file/path.h @@ -25,7 +25,7 @@ public: else return ""; } - std::string GetFriendlyPath() { + std::string GetFriendlyPath() const { std::string str = GetPath(); #if defined(__ANDROID__) // Do nothing From ff2c540e51002d28c369dfa50222929a25575c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 25 Feb 2019 21:35:16 +0100 Subject: [PATCH 21/81] Found the handle leak! Doh. --- Common/FileUtil.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Common/FileUtil.cpp b/Common/FileUtil.cpp index c6fbd73eff..a869389dd9 100644 --- a/Common/FileUtil.cpp +++ b/Common/FileUtil.cpp @@ -134,6 +134,7 @@ std::string ResolvePath(const std::string &path) { if (result >= BUF_SIZE || result == 0) wcscpy_s(buf, BUF_SIZE - 1, input.c_str()); } + CloseHandle(hFile); } else { wchar_t *longBuf = new wchar_t[BUF_SIZE]; memset(buf, 0, BUF_SIZE); From cb25354dcececae2878eb30d54d187c23429a002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 25 Feb 2019 21:48:56 +0100 Subject: [PATCH 22/81] Better place for CloseHandle --- Common/FileUtil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/FileUtil.cpp b/Common/FileUtil.cpp index a869389dd9..5ca7b0f1b9 100644 --- a/Common/FileUtil.cpp +++ b/Common/FileUtil.cpp @@ -133,8 +133,8 @@ std::string ResolvePath(const std::string &path) { int result = getFinalPathNameByHandleW(hFile, buf, BUF_SIZE - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); if (result >= BUF_SIZE || result == 0) wcscpy_s(buf, BUF_SIZE - 1, input.c_str()); + CloseHandle(hFile); } - CloseHandle(hFile); } else { wchar_t *longBuf = new wchar_t[BUF_SIZE]; memset(buf, 0, BUF_SIZE); From b8e56b361e50cefc33de79827179af8934d1d3a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 26 Feb 2019 08:57:51 +0100 Subject: [PATCH 23/81] EGL: Avoid HDR mode. Uses unknownbrackets' changes from #11839. --- SDL/SDLGLGraphicsContext.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index 42ed9a261b..af9e29fde3 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -108,8 +108,13 @@ EGLConfig EGL_FindConfig(int *contextVersion) { return val; }; - int colorScore = readConfig(EGL_RED_SIZE) + readConfig(EGL_BLUE_SIZE) + readConfig(EGL_GREEN_SIZE); - int alphaScore = readConfig(EGL_ALPHA_SIZE); + // We don't want HDR modes with more than 8 bits per component. + auto readConfigMax = [&](EGLint attr, EGLint m) -> EGLint { + EGLint val = readConfig(attr); + return val > m ? 1 : val; + }; + int colorScore = readConfigMax(EGL_RED_SIZE, 8) + readConfigMax(EGL_BLUE_SIZE, 8) + readConfigMax(EGL_GREEN_SIZE, 8); + int alphaScore = readConfigMax(EGL_ALPHA_SIZE, 8); int depthScore = readConfig(EGL_DEPTH_SIZE); int levelScore = readConfig(EGL_LEVEL) == 0 ? 100 : 0; int samplesScore = readConfig(EGL_SAMPLES) == 0 ? 100 : 0; @@ -120,6 +125,11 @@ EGLConfig EGL_FindConfig(int *contextVersion) { EGLint caveat = readConfig(EGL_CONFIG_CAVEAT); int caveatScore = caveat == EGL_NONE ? 100 : (caveat == EGL_NON_CONFORMANT_CONFIG ? 50 : 0); +#ifndef USING_FBDEV + EGLint surfaceType = readConfig(EGL_SURFACE_TYPE); + int surfaceScore = (surfaceType & EGL_WINDOW_BIT) ? 100 : (caveat == EGL_NON_CONFORMANT_CONFIG ? 50 : 0); +#endif + EGLint renderable = readConfig(EGL_RENDERABLE_TYPE); bool renderableGLES3 = (renderable & EGL_OPENGL_ES3_BIT_KHR) != 0; bool renderableGLES2 = (renderable & EGL_OPENGL_ES2_BIT) != 0; @@ -143,6 +153,10 @@ EGLConfig EGL_FindConfig(int *contextVersion) { score += levelScore + samplesScore + sampleBufferScore + transparentScore; score += caveatScore + renderableScoreGLES + renderableScoreGL; +#ifndef USING_FBDEV + score += surfaceScore; +#endif + if (score > bestScore) { bestScore = score; best = config; From 1f4c1cee2d34b0050e8318e28e16bbf32211c108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 26 Feb 2019 10:39:17 +0100 Subject: [PATCH 24/81] Disable more texcoord math on terrible-precision PowerVR (it's really awful). Fixes #9189. --- GPU/GLES/FragmentShaderGeneratorGLES.cpp | 10 ++++++++-- ext/native/gfx_es2/gpu_features.cpp | 5 ++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/GPU/GLES/FragmentShaderGeneratorGLES.cpp b/GPU/GLES/FragmentShaderGeneratorGLES.cpp index 1b063aff6a..97f319fd7e 100644 --- a/GPU/GLES/FragmentShaderGeneratorGLES.cpp +++ b/GPU/GLES/FragmentShaderGeneratorGLES.cpp @@ -311,8 +311,13 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform // TODO: Not sure the right way to do this for projection. // This path destroys resolution on older PowerVR no matter what I do if projection is needed, // so we disable it on SGX 540 and lesser, and live with the consequences. - bool badPrecision = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_TERRIBLE) != 0; - if (needShaderTexClamp && !(doTextureProjection && badPrecision)) { + bool terriblePrecision = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_TERRIBLE) != 0; + bool clampDisabled = doTextureProjection && terriblePrecision; + // Also with terrible precision we can't do wrapping without destroying the image. See #9189 + if (terriblePrecision && (!id.Bit(FS_BIT_CLAMP_S) || !id.Bit(FS_BIT_CLAMP_T))) { + clampDisabled = true; + } + if (needShaderTexClamp && !clampDisabled) { // 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. @@ -355,6 +360,7 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, uint64_t *uniform } else { if (doTextureProjection) { // We don't use textureProj because we need better control and it's probably not much of a savings anyway. + // However it is good for precision on older hardware like PowerVR. WRITE(p, " vec2 uv = %s.xy/%s.z;\n vec2 uv_round;\n", texcoord, texcoord); } else { WRITE(p, " vec2 uv = %s.xy;\n vec2 uv_round;\n", texcoord); diff --git a/ext/native/gfx_es2/gpu_features.cpp b/ext/native/gfx_es2/gpu_features.cpp index 9dc0bd7b1c..3f8a56b014 100644 --- a/ext/native/gfx_es2/gpu_features.cpp +++ b/ext/native/gfx_es2/gpu_features.cpp @@ -99,7 +99,10 @@ void ProcessGPUFeatures() { DLOG("Checking for GL driver bugs... vendor=%i model='%s'", (int)gl_extensions.gpuVendor, gl_extensions.model); if (gl_extensions.gpuVendor == GPU_VENDOR_IMGTEC) { - if (!strcmp(gl_extensions.model, "PowerVR SGX 543") || + if (!strcmp(gl_extensions.model, "PowerVR SGX 545") || + !strcmp(gl_extensions.model, "PowerVR SGX 544") || + !strcmp(gl_extensions.model, "PowerVR SGX 544MP2") || + !strcmp(gl_extensions.model, "PowerVR SGX 543") || !strcmp(gl_extensions.model, "PowerVR SGX 540") || !strcmp(gl_extensions.model, "PowerVR SGX 530") || !strcmp(gl_extensions.model, "PowerVR SGX 520") ) { From 593c3139bd4d92093691b130026b6a535146ccec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 26 Feb 2019 15:21:21 +0100 Subject: [PATCH 25/81] Ignore DisableAccurateDepth on Adreno as well. Fixes #11557 --- GPU/Vulkan/GPU_Vulkan.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 5ad07c0ca4..954bfb2bde 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -188,6 +188,10 @@ void GPU_Vulkan::CheckGPUFeatures() { // Accurate depth is required on AMD (due to reverse-Z driver bug) so we ignore the compat flag to disable it on those. See #9545 features |= GPU_SUPPORTS_ACCURATE_DEPTH; break; + case VULKAN_VENDOR_QUALCOMM: + // Accurate depth is required on Adreno too (seems to also have a reverse-Z driver bug). + features |= GPU_SUPPORTS_ACCURATE_DEPTH; + break; case VULKAN_VENDOR_ARM: // Also required on older ARM Mali drivers, like the one on many Galaxy S7. if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth || From 8e7da3fef44aee60e790850f275efb4e4e2b7505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 26 Feb 2019 16:07:11 +0100 Subject: [PATCH 26/81] Disable vertex range culling when the depthrange hack is enabled. Temporary workaround for #11576. --- GPU/D3D11/GPU_D3D11.cpp | 4 +++- GPU/Directx9/GPU_DX9.cpp | 28 +++++++++++++++------------- GPU/GLES/GPU_GLES.cpp | 4 +++- GPU/Vulkan/GPU_Vulkan.cpp | 4 +++- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index e0ee48ef05..9f2c4474e9 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -127,7 +127,9 @@ GPU_D3D11::~GPU_D3D11() { void GPU_D3D11::CheckGPUFeatures() { u32 features = 0; - features |= GPU_SUPPORTS_VS_RANGE_CULLING; + if (!PSP_CoreParameter().compat.flags().DepthRangeHack) { + features |= GPU_SUPPORTS_VS_RANGE_CULLING; + } features |= GPU_SUPPORTS_BLEND_MINMAX; features |= GPU_PREFER_CPU_DOWNLOAD; diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 62b3caf1c2..2a2d3ecda0 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -176,21 +176,23 @@ void GPU_DX9::CheckGPUFeatures() { features |= GPU_SUPPORTS_ACCURATE_DEPTH; } - // VS range culling (killing triangles in the vertex shader using NaN) causes problems on Intel. - // Also causes problems on old NVIDIA. - switch (vendor) { - case Draw::GPUVendor::VENDOR_INTEL: - break; - case Draw::GPUVendor::VENDOR_NVIDIA: - // Older NVIDIAs don't seem to like NaNs in their DX9 vertex shaders. - // No idea if KEPLER is the right cutoff, but let's go with it. - if (NVIDIAGetDeviceGeneration(draw_->GetDeviceCaps().deviceID) >= NV_KEPLER) { + if (!PSP_CoreParameter().compat.flags().DepthRangeHack) { + // VS range culling (killing triangles in the vertex shader using NaN) causes problems on Intel. + // Also causes problems on old NVIDIA. + switch (vendor) { + case Draw::GPUVendor::VENDOR_INTEL: + break; + case Draw::GPUVendor::VENDOR_NVIDIA: + // Older NVIDIAs don't seem to like NaNs in their DX9 vertex shaders. + // No idea if KEPLER is the right cutoff, but let's go with it. + if (NVIDIAGetDeviceGeneration(draw_->GetDeviceCaps().deviceID) >= NV_KEPLER) { + features |= GPU_SUPPORTS_VS_RANGE_CULLING; + } + break; + default: features |= GPU_SUPPORTS_VS_RANGE_CULLING; + break; } - break; - default: - features |= GPU_SUPPORTS_VS_RANGE_CULLING; - break; } D3DCAPS9 caps; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index bb54322f7f..967aaf6709 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -149,7 +149,9 @@ void GPU_GLES::CheckGPUFeatures() { features |= GPU_SUPPORTS_16BIT_FORMATS; if (!draw_->GetBugs().Has(Draw::Bugs::BROKEN_NAN_IN_CONDITIONAL)) { - features |= GPU_SUPPORTS_VS_RANGE_CULLING; + if (!PSP_CoreParameter().compat.flags().DepthRangeHack) { + features |= GPU_SUPPORTS_VS_RANGE_CULLING; + } } if (gl_extensions.ARB_blend_func_extended || gl_extensions.EXT_blend_func_extended) { diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 954bfb2bde..ca9f0d273b 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -181,7 +181,9 @@ GPU_Vulkan::~GPU_Vulkan() { void GPU_Vulkan::CheckGPUFeatures() { uint32_t features = 0; - features |= GPU_SUPPORTS_VS_RANGE_CULLING; + if (!PSP_CoreParameter().compat.flags().DepthRangeHack) { + features |= GPU_SUPPORTS_VS_RANGE_CULLING; + } switch (vulkan_->GetPhysicalDeviceProperties().properties.vendorID) { case VULKAN_VENDOR_AMD: From e49c488c6ff0fb178734df5fca4a5f607c41226c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 27 Feb 2019 10:05:15 +0100 Subject: [PATCH 27/81] Silence a compiler warning, fix an uninitialized variable --- Core/Dialog/PSPSaveDialog.cpp | 16 ++++++++-------- UI/MainScreen.cpp | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index c06a436152..d078382897 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -403,7 +403,7 @@ void PSPSaveDialog::DisplaySaveDataInfo1() char saveDetail[1024]; char am_pm[] = "AM"; - char hour_time[10] ; + char hour_time[32]; int hour = param.GetFileInfo(currentSelectedSave).modif_time.tm_hour; int min = param.GetFileInfo(currentSelectedSave).modif_time.tm_min; switch (g_Config.iTimeFormat) { @@ -412,17 +412,17 @@ void PSPSaveDialog::DisplaySaveDataInfo1() strcpy(am_pm, "PM"); hour -= 12; } - snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm); + snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm); break; case 2: - snprintf(hour_time,10,"%02d:%02d", hour, min); + snprintf(hour_time, sizeof(hour_time), "%02d:%02d", hour, min); break; default: if (hour > 12) { strcpy(am_pm, "PM"); hour -= 12; } - snprintf(hour_time,10,"%02d:%02d %s", hour, min, am_pm); + snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm); } snprintf(title, sizeof(title), "%s", param.GetFileInfo(currentSelectedSave).title); @@ -485,7 +485,7 @@ void PSPSaveDialog::DisplaySaveDataInfo2(bool showNewData) { char date[256]; char am_pm[] = "AM"; - char hour_time[10] ; + char hour_time[32]; int hour = modif_time.tm_hour; int min = modif_time.tm_min; switch (g_Config.iTimeFormat) { @@ -494,17 +494,17 @@ void PSPSaveDialog::DisplaySaveDataInfo2(bool showNewData) { strcpy(am_pm, "PM"); hour -= 12; } - snprintf(hour_time, 10, "%02d:%02d %s", hour, min, am_pm); + snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm); break; case 2: - snprintf(hour_time, 10, "%02d:%02d", hour, min); + snprintf(hour_time, sizeof(hour_time), "%02d:%02d", hour, min); break; default: if (hour > 12) { strcpy(am_pm, "PM"); hour -= 12; } - snprintf(hour_time, 10, "%02d:%02d %s", hour, min, am_pm); + snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm); } int day = modif_time.tm_mday; diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 46b80d64be..3385d49af8 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -114,8 +114,8 @@ static bool IsTempPath(const std::string &str) { class GameButton : public UI::Clickable { public: - GameButton(const std::string &gamePath, bool gridStyle, UI::LayoutParams *layoutParams = 0) - : UI::Clickable(layoutParams), gridStyle_(gridStyle), gamePath_(gamePath), holdStart_(0), holdEnabled_(true) {} + GameButton(const std::string &gamePath, bool gridStyle, UI::LayoutParams *layoutParams = 0) + : UI::Clickable(layoutParams), gridStyle_(gridStyle), gamePath_(gamePath) {} void Draw(UIContext &dc) override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override { @@ -206,9 +206,9 @@ private: std::string gamePath_; std::string title_; - double holdStart_; - bool holdEnabled_; - bool hovering_; + double holdStart_ = 0.0; + bool holdEnabled_ = true; + bool hovering_ = false; }; void GameButton::Draw(UIContext &dc) { @@ -404,7 +404,7 @@ void DirButton::Draw(UIContext &dc) { if (text == "..") { image = I_UP_DIRECTORY; } - + float tw, th; dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, text.c_str(), &tw, &th, 0); From e715fe038272b0653c6cc9c93bd9bd45a2853875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 27 Feb 2019 10:32:51 +0100 Subject: [PATCH 28/81] EGL errors should cause us to bail. Also downweight alpha in the EGL config chooser. See #11839 --- SDL/SDLGLGraphicsContext.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index af9e29fde3..1bd6667233 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -27,10 +27,9 @@ static Display* g_Display = NULL; #endif static NativeWindowType g_Window = (NativeWindowType)NULL; -int8_t CheckEGLErrors(const std::string& file, uint16_t line) { +int CheckEGLErrors(const char *file, int line) { EGLenum error; - std::string errortext; - + const char *errortext = "unknown"; error = eglGetError(); switch (error) { @@ -50,7 +49,7 @@ int8_t CheckEGLErrors(const std::string& file, uint16_t line) { case EGL_BAD_NATIVE_WINDOW: errortext = "EGL_BAD_NATIVE_WINDOW"; break; default: errortext = "unknown"; break; } - printf( "ERROR: EGL Error detected in file %s at line %d: %s (0x%X)\n", file.c_str(), line, errortext.c_str(), error ); + printf( "ERROR: EGL Error %s detected in file %s at line %d (0x%X)\n", errortext, file, line, error ); return 1; } @@ -111,7 +110,7 @@ EGLConfig EGL_FindConfig(int *contextVersion) { // We don't want HDR modes with more than 8 bits per component. auto readConfigMax = [&](EGLint attr, EGLint m) -> EGLint { EGLint val = readConfig(attr); - return val > m ? 1 : val; + return val > m ? 1 : val; // why not 0? }; int colorScore = readConfigMax(EGL_RED_SIZE, 8) + readConfigMax(EGL_BLUE_SIZE, 8) + readConfigMax(EGL_GREEN_SIZE, 8); int alphaScore = readConfigMax(EGL_ALPHA_SIZE, 8); @@ -127,7 +126,7 @@ EGLConfig EGL_FindConfig(int *contextVersion) { #ifndef USING_FBDEV EGLint surfaceType = readConfig(EGL_SURFACE_TYPE); - int surfaceScore = (surfaceType & EGL_WINDOW_BIT) ? 100 : (caveat == EGL_NON_CONFORMANT_CONFIG ? 50 : 0); + int surfaceScore = (surfaceType & EGL_WINDOW_BIT) ? 100 : 0; #endif EGLint renderable = readConfig(EGL_RENDERABLE_TYPE); @@ -148,7 +147,7 @@ EGLConfig EGL_FindConfig(int *contextVersion) { int score = 0; // Here's a good place to play with the weights to pick a better config. - score += (colorScore + alphaScore) * 10; + score += colorScore * 10 + alphaScore * 2; score += depthScore * 5 + stencilScore; score += levelScore + samplesScore + sampleBufferScore + transparentScore; score += caveatScore + renderableScoreGLES + renderableScoreGL; @@ -173,6 +172,7 @@ int8_t EGL_Init() { EGLConfig eglConfig = EGL_FindConfig(&contextVersion); if (!eglConfig) { EGL_ERROR("Unable to find a usable EGL config.", true); + return 1; } EGLint contextAttributes[] = { @@ -186,10 +186,11 @@ int8_t EGL_Init() { g_eglContext = eglCreateContext(g_eglDisplay, eglConfig, nullptr, contextAttributes); if (g_eglContext == EGL_NO_CONTEXT) { EGL_ERROR("Unable to create GLES context!", true); + return 1; } #if !defined(USING_FBDEV) && !defined(__APPLE__) - //Get the SDL window handle + // Get the SDL window handle SDL_SysWMinfo sysInfo; //Will hold our Window information SDL_VERSION(&sysInfo.version); //Set SDL version g_Window = (NativeWindowType)sysInfo.info.x11.window; @@ -197,11 +198,15 @@ int8_t EGL_Init() { g_Window = (NativeWindowType)NULL; #endif g_eglSurface = eglCreateWindowSurface(g_eglDisplay, eglConfig, g_Window, nullptr); - if (g_eglSurface == EGL_NO_SURFACE) + if (g_eglSurface == EGL_NO_SURFACE) { EGL_ERROR("Unable to create EGL surface!", true); + return 1; + } - if (eglMakeCurrent(g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext) != EGL_TRUE) + if (eglMakeCurrent(g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext) != EGL_TRUE) { EGL_ERROR("Unable to make GLES context current.", true); + return 1; + } return 0; } @@ -310,7 +315,10 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std: SDL_ShowWindow(window); #ifdef USING_EGL - EGL_Init(); + if (EGL_Init() != 0) { + printf("EGL_Init() failed\n"); + return 1; + } #endif #ifndef USING_GLES2 From d7f3f15b85821000e92817e04090d0e9cdbf9dc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 27 Feb 2019 11:26:31 +0100 Subject: [PATCH 29/81] Add missing line to SDL EGL init (no way this path could have worked anywhere?) --- SDL/SDLGLGraphicsContext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index 1bd6667233..1f3269a4df 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -193,6 +193,7 @@ int8_t EGL_Init() { // Get the SDL window handle SDL_SysWMinfo sysInfo; //Will hold our Window information SDL_VERSION(&sysInfo.version); //Set SDL version + SDL_GetWindowWMInfo(window, &sysInfo); g_Window = (NativeWindowType)sysInfo.info.x11.window; #else g_Window = (NativeWindowType)NULL; From bd71af24db441d8a64b86af15034cf97bcf2204b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 27 Feb 2019 13:42:00 +0100 Subject: [PATCH 30/81] Fix some minor things found looking at Valgrind output --- Common/FileUtil.cpp | 2 +- Core/Dialog/PSPMsgDialog.cpp | 2 +- Core/HLE/sceMpeg.cpp | 8 +++++--- Core/Util/PPGeDraw.cpp | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Common/FileUtil.cpp b/Common/FileUtil.cpp index 5ca7b0f1b9..69504428eb 100644 --- a/Common/FileUtil.cpp +++ b/Common/FileUtil.cpp @@ -830,7 +830,7 @@ const std::string &GetExeDirectory() uint32_t program_path_size = sizeof(program_path) - 1; #if defined(__linux__) - if (readlink("/proc/self/exe", program_path, 4095) > 0) + if (readlink("/proc/self/exe", program_path, program_path_size) > 0) #elif defined(__APPLE__) && !defined(IOS) if (_NSGetExecutablePath(program_path, &program_path_size) == 0) #elif defined(KERN_PROC_PATHNAME) diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index 302113b3b5..ca9e283f3e 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -146,7 +146,7 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) float WRAP_WIDTH = 300.0f; if (UTF8StringNonASCIICount(text.c_str()) > 3) WRAP_WIDTH = 372.0f; - + float y = 140.0f; float h, sy ,ey; int n; diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index a76a216fa4..43f30b9ce6 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -318,12 +318,12 @@ static void AnalyzeMpeg(u8 *buffer, u32 validSize, MpegContext *ctx) { ctx->audioFrameCount = 0; ctx->endOfAudioReached = false; ctx->endOfVideoReached = false; - + // Sanity Check ctx->mpegFirstTimestamp if (ctx->mpegFirstTimestamp != 90000) { WARN_LOG_REPORT(ME, "Unexpected mpeg first timestamp: %llx / %lld", ctx->mpegFirstTimestamp, ctx->mpegFirstTimestamp); } - + if (ctx->mpegMagic != PSMF_MAGIC || ctx->mpegVersion < 0 || (ctx->mpegOffset & 2047) != 0 || ctx->mpegOffset == 0) { // mpeg header is invalid! @@ -511,7 +511,7 @@ static u32 sceMpegCreate(u32 mpegAddr, u32 dataPtr, u32 size, u32 ringbufferAddr Memory::Write_U32(ringbufferAddr, mpegHandle + 16); Memory::Write_U32(ringbuffer->dataUpperBound, mpegHandle + 20); } - MpegContext *ctx = new MpegContext; + MpegContext *ctx = new MpegContext(); if (mpegMap.find(mpegHandle) != mpegMap.end()) { WARN_LOG_REPORT(HLE, "Replacing existing mpeg context at %08x", mpegAddr); // Otherwise, it would leak. @@ -532,6 +532,8 @@ static u32 sceMpegCreate(u32 mpegAddr, u32 dataPtr, u32 size, u32 ringbufferAddr ctx->ignorePcm = false; ctx->ignoreAvc = false; ctx->defaultFrameWidth = frameWidth; + ctx->mpegStreamSize = 0; + ctx->mpegOffset = 0; for (int i = 0; i < MPEG_DATA_ES_BUFFERS; i++) { ctx->esBuffers[i] = false; } diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 74dc3baa8d..d0bd9ae4c7 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -477,7 +477,7 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, utfWord = utfPrev; finished = true; break; - } + } } } ++numChars; @@ -549,7 +549,7 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, } lineWidth += nextWidth; - u32 cval = utf.next(); + u32 cval = utf.end() ? 0 : utf.next(); if (spaceWidth > 0) { if (!dryRun) From aba375e2f7498072962135a141006f1aa956f158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 28 Feb 2019 14:16:20 +0100 Subject: [PATCH 31/81] Remove old resolution hackery that didn't fix anything. --- android/jni/app-android.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 2180522782..e638d7e2a8 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -882,11 +882,6 @@ void getDesiredBackbufferSize(int &sz_x, int &sz_y) { sz_x = 0; sz_y = 0; } - // Round the size up to the nearest multiple of 4. While this may cause a tiny aspect ratio distortion, - // there's some hope that #11151 is a driver bug that might be worked around this way. If this fixes it, - // it'll be worth trying to round to a multiple of 2 instead. - sz_x = (sz_x + 3) & ~3; - sz_y = (sz_y + 3) & ~3; } extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_setDisplayParameters(JNIEnv *, jclass, jint xres, jint yres, jint dpi, jfloat refreshRate) { From 84d41a776cdcd57ee9872e4899acf5a6cff946f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 1 Mar 2019 08:12:02 +0100 Subject: [PATCH 32/81] compat: Enable 60fps limit and warning for wrong clock freq for Tekken 6. --- assets/compat.ini | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/assets/compat.ini b/assets/compat.ini index 620f55b170..e3ee932eba 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -430,6 +430,9 @@ UCES01473 = true NPJG90095 = true NPEG90035 = true NPUG70125 = true +# Tekken 6 +ULES01376 = true +ULUS10466 = true [MGS2AcidHack] ULES00008 = true @@ -551,3 +554,7 @@ UCES00238 = true UCJS10045 = true # F1 2005, japan only? UCJS10019 = true + +# Tekken 6 +ULES01376 = true +ULUS10466 = true From e90328d03c8d629a7e564f069aa48fc75fa1f171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 1 Mar 2019 08:20:42 +0100 Subject: [PATCH 33/81] UWP: Restore the Load button. Fixes #11855. --- UI/MainScreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 3385d49af8..c6e4965b66 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -903,7 +903,7 @@ void MainScreen::CreateViews() { TextView *ver = rightColumnItems->Add(new TextView(versionString, new LinearLayoutParams(Margins(70, -6, 0, 0)))); ver->SetSmall(true); ver->SetClip(false); -#if defined(USING_WIN_UI) || defined(USING_QT_UI) +#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP) rightColumnItems->Add(new Choice(mm->T("Load","Load...")))->OnClick.Handle(this, &MainScreen::OnLoadFile); #endif rightColumnItems->Add(new Choice(mm->T("Game Settings", "Settings")))->OnClick.Handle(this, &MainScreen::OnGameSettings); From 2d5acc83b65aaccdeb5f36dc7ba135fee85fefc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 1 Mar 2019 08:35:35 +0100 Subject: [PATCH 34/81] Use MSG_NOSIGNAL for some more send() calls. Didn't fix anything though. See #11853 --- ext/native/net/sinks.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ext/native/net/sinks.cpp b/ext/native/net/sinks.cpp index e011f33453..d9bf32d9d0 100644 --- a/ext/native/net/sinks.cpp +++ b/ext/native/net/sinks.cpp @@ -25,6 +25,11 @@ #include "net/sinks.h" #include "file/fd_util.h" +#ifndef MSG_NOSIGNAL +// Default value to 0x00 (do nothing) in systems where it's not supported +#define MSG_NOSIGNAL 0 +#endif + namespace net { InputSink::InputSink(size_t fd) : fd_(fd), read_(0), write_(0), valid_(0) { @@ -243,7 +248,7 @@ size_t OutputSink::PushAtMost(const char *buf, size_t bytes) { if (valid_ == 0 && bytes > PRESSURE) { // Special case for pushing larger buffers: let's try to send directly. - int sentBytes = send(fd_, buf, (int)bytes, 0); + int sentBytes = send(fd_, buf, (int)bytes, MSG_NOSIGNAL); // If it was 0 or EWOULDBLOCK, that's fine, we'll enqueue as we can. if (sentBytes > 0) { return sentBytes; @@ -325,7 +330,7 @@ bool OutputSink::Flush(bool allowBlock) { while (valid_ > 0) { size_t avail = std::min(BUFFER_SIZE - read_, valid_); - int bytes = send(fd_, buf_ + read_, (int)avail, 0); + int bytes = send(fd_, buf_ + read_, (int)avail, MSG_NOSIGNAL); AccountDrain(bytes); if (bytes == 0) { @@ -353,7 +358,7 @@ void OutputSink::Drain() { // Let's just do contiguous valid. size_t avail = std::min(BUFFER_SIZE - read_, valid_); - int bytes = send(fd_, buf_ + read_, (int)avail, 0); + int bytes = send(fd_, buf_ + read_, (int)avail, MSG_NOSIGNAL); AccountDrain(bytes); } } From 17b4f28d6b692339192c96e87815b84597a1e15d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 1 Mar 2019 10:55:43 +0100 Subject: [PATCH 35/81] Hardcode the cheats that work around the Tony Hawk jit issues. Temporary, horrible hack working around #3854. --- Core/Compatibility.cpp | 1 + Core/Compatibility.h | 1 + Core/CwCheat.cpp | 47 +++++++++++++++++++++++++++++++++--------- Core/CwCheat.h | 2 +- assets/compat.ini | 13 ++++++++++++ 5 files changed, 53 insertions(+), 11 deletions(-) diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index d5574488d1..ed396a8a34 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -63,6 +63,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "YugiohSaveFix", &flags_.YugiohSaveFix); CheckSetting(iniFile, gameID, "ForceUMDDelay", &flags_.ForceUMDDelay); CheckSetting(iniFile, gameID, "ForceMax60FPS", &flags_.ForceMax60FPS); + CheckSetting(iniFile, gameID, "JitInvalidationHack", &flags_.JitInvalidationHack); } void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool *flag) { diff --git a/Core/Compatibility.h b/Core/Compatibility.h index c5a46ba9a2..1db5d52de8 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -63,6 +63,7 @@ struct CompatFlags { bool YugiohSaveFix; bool ForceUMDDelay; bool ForceMax60FPS; + bool JitInvalidationHack; }; class IniFile; diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 5722145ef5..29e016244b 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -237,6 +237,21 @@ static void __CheatStart() { cheatsEnabled = true; } +static int GetRefreshMs() { + int refresh = g_Config.iCwCheatRefreshRate; + + if (!cheatsEnabled) + refresh = 1000; + + // Horrible hack for Tony Hawk - Underground 2. See #3854. Avoids crashing somehow + // but still causes regular JIT invalidations which causes stutters. + if (PSP_CoreParameter().compat.flags().JitInvalidationHack) { + refresh = 2; + } + + return refresh; +} + void __CheatInit() { // Always register the event, want savestates to be compatible whether cheats on or off. CheatEvent = CoreTiming::RegisterEvent("CheatEvent", &hleCheat); @@ -245,10 +260,8 @@ void __CheatInit() { __CheatStart(); } - int refresh = g_Config.iCwCheatRefreshRate; - // Only check once a second for cheats to be enabled. - CoreTiming::ScheduleEvent(msToCycles(cheatsEnabled ? refresh : 1000), CheatEvent, 0); + CoreTiming::ScheduleEvent(msToCycles(GetRefreshMs()), CheatEvent, 0); } void __CheatShutdown() { @@ -264,13 +277,11 @@ void __CheatDoState(PointerWrap &p) { p.Do(CheatEvent); CoreTiming::RestoreRegisterEvent(CheatEvent, "CheatEvent", &hleCheat); - int refresh = g_Config.iCwCheatRefreshRate; - if (s < 2) { // Before this we didn't have a checkpoint, so reset didn't work. // Let's just force one in. CoreTiming::RemoveEvent(CheatEvent); - CoreTiming::ScheduleEvent(msToCycles(cheatsEnabled ? refresh : 1000), CheatEvent, 0); + CoreTiming::ScheduleEvent(msToCycles(GetRefreshMs()), CheatEvent, 0); } } @@ -284,14 +295,30 @@ void hleCheat(u64 userdata, int cyclesLate) { } } - int refresh = g_Config.iCwCheatRefreshRate; + // Check periodically for cheats. + CoreTiming::ScheduleEvent(msToCycles(GetRefreshMs()), CheatEvent, 0); - // Only check once a second for cheats to be enabled. - CoreTiming::ScheduleEvent(msToCycles(cheatsEnabled ? refresh : 1000), CheatEvent, 0); + if (PSP_CoreParameter().compat.flags().JitInvalidationHack) { + std::string gameTitle = g_paramSFO.GetValueString("DISC_ID"); + + // Horrible hack for Tony Hawk - Underground 2. See #3854. Avoids crashing somehow + // but still causes regular JIT invalidations which causes stutters. + if (gameTitle == "ULUS10014") { + cheatEngine->InvalidateICache(0x08865600, 72); + cheatEngine->InvalidateICache(0x08865690, 4); + } else if (gameTitle == "ULES00033") { // euro, also 34 and 35 + cheatEngine->InvalidateICache(0x088655D8, 72); + cheatEngine->InvalidateICache(0x08865668, 4); + } else if (gameTitle == "ULUS10138") { // MTX MotoTrax. No hack for ULES00581 known. + cheatEngine->InvalidateICache(0x0886DCC0, 72); + cheatEngine->InvalidateICache(0x0886DC20, 4); + cheatEngine->InvalidateICache(0x0886DD40, 4); + } + } if (!cheatEngine || !cheatsEnabled) return; - + if (g_Config.bReloadCheats) { //Checks if the "reload cheats" button has been pressed. cheatEngine->ParseCheats(); g_Config.bReloadCheats = false; diff --git a/Core/CwCheat.h b/Core/CwCheat.h index cef0002289..882093db3d 100644 --- a/Core/CwCheat.h +++ b/Core/CwCheat.h @@ -45,8 +45,8 @@ public: void Run(); bool HasCheats(); -private: void InvalidateICache(u32 addr, int size); +private: u32 GetAddress(u32 value); CheatOperation InterpretNextOp(const CheatCode &cheat, size_t &i); diff --git a/assets/compat.ini b/assets/compat.ini index e3ee932eba..0f44f0ff56 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -558,3 +558,16 @@ UCJS10019 = true # Tekken 6 ULES01376 = true ULUS10466 = true + +[JitInvalidationHack] +# This is an absolutely awful hack that somehow prevents issues when clearing the JIT, +# if the game has copied code with EmuHack opcodes or something. Hopefully will be able +# to remove this in the future. +# See #3854. +# Tony Hawk's Underground +ULUS10014 = true +ULES00033 = true +ULES00034 = true +ULES00035 = true +# MTX MotoTrax +ULUS10138 = true From c84137dd2d1ce22f8c9736d46e78e29fb31a6050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 1 Mar 2019 14:31:28 +0100 Subject: [PATCH 36/81] Add the other gameIDs for euro tony hawk --- Core/CwCheat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 29e016244b..8c62c42e3a 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -306,7 +306,7 @@ void hleCheat(u64 userdata, int cyclesLate) { if (gameTitle == "ULUS10014") { cheatEngine->InvalidateICache(0x08865600, 72); cheatEngine->InvalidateICache(0x08865690, 4); - } else if (gameTitle == "ULES00033") { // euro, also 34 and 35 + } else if (gameTitle == "ULES00033" || gameTitle == "ULES00034" || gameTitle == "ULES00035") { // euro, also 34 and 35 cheatEngine->InvalidateICache(0x088655D8, 72); cheatEngine->InvalidateICache(0x08865668, 4); } else if (gameTitle == "ULUS10138") { // MTX MotoTrax. No hack for ULES00581 known. From 357e0316a054df6e722c530fb4412c6a8a4228bc Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 2 Mar 2019 10:48:01 -0800 Subject: [PATCH 37/81] GPU: Handle cull range properly drawing at offset. Did the transformation backwards. --- GPU/Common/ShaderUniforms.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index f8fb3456e9..8823c764c1 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -30,7 +30,7 @@ void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bo // Account for the projection viewport adjustment when viewport is too large. auto reverseViewportX = [](float x) { float pspViewport = (x - gstate.getViewportXCenter()) * (1.0f / gstate.getViewportXScale()); - return (pspViewport - gstate_c.vpXOffset) * gstate_c.vpWidthScale; + return (pspViewport * gstate_c.vpWidthScale) - gstate_c.vpXOffset; }; auto reverseViewportY = [flipViewport](float y) { float heightScale = gstate_c.vpHeightScale; @@ -39,7 +39,7 @@ void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bo heightScale = -heightScale; } float pspViewport = (y - gstate.getViewportYCenter()) * (1.0f / gstate.getViewportYScale()); - return (pspViewport - gstate_c.vpYOffset) * heightScale; + return (pspViewport * heightScale) - gstate_c.vpYOffset; }; auto reverseViewportZ = [hasNegZ](float z) { float vpZScale = gstate.getViewportZScale(); From d7f2167898d7c8b98a369f938a9cb3eb7198866b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 2 Mar 2019 10:57:49 -0800 Subject: [PATCH 38/81] GLES: Correct cull range offset in unbuffered. --- GPU/Common/ShaderUniforms.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index 8823c764c1..46ad4470e2 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -34,12 +34,14 @@ void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bo }; auto reverseViewportY = [flipViewport](float y) { float heightScale = gstate_c.vpHeightScale; + float yOffset = gstate_c.vpYOffset; if (flipViewport) { // For D3D11 and GLES non-buffered. heightScale = -heightScale; + yOffset = -yOffset; } float pspViewport = (y - gstate.getViewportYCenter()) * (1.0f / gstate.getViewportYScale()); - return (pspViewport * heightScale) - gstate_c.vpYOffset; + return (pspViewport * heightScale) - yOffset; }; auto reverseViewportZ = [hasNegZ](float z) { float vpZScale = gstate.getViewportZScale(); From 15ac3da11633f207f8997b314e3c5e679b9db851 Mon Sep 17 00:00:00 2001 From: 6alileo <42245908+6alileo@users.noreply.github.com> Date: Sat, 2 Mar 2019 12:40:40 -0800 Subject: [PATCH 39/81] Hori Minipad S --- UWP/Content/gamecontrollerdb.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/UWP/Content/gamecontrollerdb.txt b/UWP/Content/gamecontrollerdb.txt index 6f6e6363b5..ce914ffbaa 100644 --- a/UWP/Content/gamecontrollerdb.txt +++ b/UWP/Content/gamecontrollerdb.txt @@ -153,3 +153,4 @@ d814000000000000cecf000000000000,MC Cthulhu,platform:Mac OS X,leftx:,lefty:,righ 05000000380700006652000025010000,Mad Catz C.T.R.L.R ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, 03000000380700008532000010010000,MadCatz Madcatz Fightpad,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:b5,righttrigger:b7, 030000000d0f0000ee00000011010000,HORI CO.,LTD. HORIPAD mini4,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +030000000d0f0000c100000011010000,HORI CO.,LTD. HORIPAD S,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, From 662f6743d0ba310398c712c778e33d9c3ebc21ff Mon Sep 17 00:00:00 2001 From: 6alileo <42245908+6alileo@users.noreply.github.com> Date: Sat, 2 Mar 2019 12:41:01 -0800 Subject: [PATCH 40/81] Update gamecontrollerdb.txt --- assets/gamecontrollerdb.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/gamecontrollerdb.txt b/assets/gamecontrollerdb.txt index 885bb1c744..a4a6c7e528 100644 --- a/assets/gamecontrollerdb.txt +++ b/assets/gamecontrollerdb.txt @@ -191,3 +191,4 @@ bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,b 05000000c82d00000161000000010000,8Bitdo SN30 Pro,platform:Linux,a:b1,b:b0,x:b4,y:b3,back:b10,guide:b2,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4, 03000000380700008532000010010000,MadCatz Madcatz Fightpad,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:b5,righttrigger:b7, 030000000d0f0000ee00000011010000,HORI CO.,LTD. HORIPAD mini4,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +030000000d0f0000c100000011010000,HORI CO.,LTD. HORIPAD S,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, From e74be9c4920194cc5292922b85e48ade2bba6b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 3 Mar 2019 09:18:11 +0100 Subject: [PATCH 41/81] DPI fixes in the old Win32 debugger. Fixes #11856. Also some general cleanup of it but decided it wasn't worth it to continue. --- Windows/Debugger/CtrlDisAsmView.cpp | 23 +++++--- Windows/Debugger/CtrlMemView.cpp | 34 ++++++----- Windows/Debugger/CtrlRegisterList.cpp | 85 +++++++++++---------------- Windows/Debugger/CtrlRegisterList.h | 28 ++++----- 4 files changed, 80 insertions(+), 90 deletions(-) diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 93d4ed6178..fdf4de758c 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -21,6 +21,7 @@ #include "Common/CommonWindows.h" #include "util/text/utf8.h" #include "ext/xxhash.h" +#include "base/display.h" #include #include @@ -154,17 +155,21 @@ CtrlDisAsmView::CtrlDisAsmView(HWND _wnd) wnd=_wnd; SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)this); SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd,GWL_STYLE) | WS_VSCROLL); - SetScrollRange(wnd, SB_VERT, -1,1,TRUE); + SetScrollRange(wnd, SB_VERT, -1, 1, TRUE); - charWidth = g_Config.iFontWidth; - rowHeight = g_Config.iFontHeight+2; + const float fontScale = 1.0f / g_dpi_scale_real_y; + charWidth = g_Config.iFontWidth * fontScale; + rowHeight = (g_Config.iFontHeight + 2) * fontScale; + int scaledFontHeight = g_Config.iFontHeight * fontScale; + font = CreateFont(scaledFontHeight, charWidth, 0, 0, + FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, + L"Lucida Console"); + boldfont = CreateFont(scaledFontHeight, charWidth, 0, 0, + FW_DEMIBOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, + L"Lucida Console"); - font = CreateFont(rowHeight-2,charWidth,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH, - L"Lucida Console"); - boldfont = CreateFont(rowHeight-2,charWidth,0,0,FW_DEMIBOLD,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH, - L"Lucida Console"); - curAddress=0; - showHex=false; + curAddress = 0; + showHex = false; hasFocus = false; dontRedraw = false; keyTaken = false; diff --git a/Windows/Debugger/CtrlMemView.cpp b/Windows/Debugger/CtrlMemView.cpp index ff28e1b99d..331126a00e 100644 --- a/Windows/Debugger/CtrlMemView.cpp +++ b/Windows/Debugger/CtrlMemView.cpp @@ -4,12 +4,13 @@ #include #include "Core/Config.h" -#include "../resource.h" -#include "../../Core/MemMap.h" -#include "../W32Util/Misc.h" +#include "Windows/resource.h" +#include "Core/MemMap.h" +#include "Windows/W32Util/Misc.h" #include "Windows/InputBox.h" -#include "../Main.h" -#include "../../Core/Debugger/SymbolMap.h" +#include "Windows/main.h" +#include "Core/Debugger/SymbolMap.h" +#include "base/display.h" #include "Debugger_Disasm.h" #include "DebuggerShared.h" @@ -26,19 +27,20 @@ CtrlMemView::CtrlMemView(HWND _wnd) SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd,GWL_STYLE) | WS_VSCROLL); SetScrollRange(wnd, SB_VERT, -1,1,TRUE); - rowHeight = g_Config.iFontHeight; - charWidth = g_Config.iFontWidth; - offsetPositionY = offsetLine*rowHeight; + const float fontScale = 1.0f / g_dpi_scale_real_y; + rowHeight = g_Config.iFontHeight * fontScale; + charWidth = g_Config.iFontWidth * fontScale; + offsetPositionY = offsetLine * rowHeight; - font = - CreateFont(rowHeight,charWidth,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS, - CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,L"Lucida Console"); - underlineFont = - CreateFont(rowHeight,charWidth,0,0,FW_DONTCARE,FALSE,TRUE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS, - CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,L"Lucida Console"); - curAddress=0; + font = CreateFont(rowHeight, charWidth, 0, 0, + FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, + L"Lucida Console"); + underlineFont = CreateFont(rowHeight, charWidth, 0, 0, + FW_DONTCARE, FALSE, TRUE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, + L"Lucida Console"); + curAddress = 0; debugger = 0; - + searchQuery = ""; matchAddress = -1; searching = false; diff --git a/Windows/Debugger/CtrlRegisterList.cpp b/Windows/Debugger/CtrlRegisterList.cpp index 6a9241be81..563a2b47f1 100644 --- a/Windows/Debugger/CtrlRegisterList.cpp +++ b/Windows/Debugger/CtrlRegisterList.cpp @@ -3,11 +3,12 @@ #include #include +#include "base/display.h" #include "util/text/utf8.h" -#include "../resource.h" +#include "Windows/resource.h" #include "Core/MemMap.h" -#include "../W32Util/Misc.h" -#include "../InputBox.h" +#include "Windows/W32Util/Misc.h" +#include "Windows/InputBox.h" #include "CtrlRegisterList.h" #include "Debugger_MemoryDlg.h" @@ -16,11 +17,10 @@ #include "Debugger_Disasm.h" #include "DebuggerShared.h" -#include "../main.h" +#include "Windows/main.h" static const int numCPUs = 1; -//#include "DbgHelp.h" extern HMENU g_hPopupMenus; enum { REGISTER_PC = 32, REGISTER_HI, REGISTER_LO, REGISTERS_END }; @@ -29,23 +29,22 @@ TCHAR CtrlRegisterList::szClassName[] = _T("CtrlRegisterList"); void CtrlRegisterList::init() { - WNDCLASSEX wc; - - wc.cbSize = sizeof(wc); - wc.lpszClassName = szClassName; - wc.hInstance = GetModuleHandle(0); - wc.lpfnWndProc = CtrlRegisterList::wndProc; - wc.hCursor = LoadCursor (NULL, IDC_ARROW); - wc.hIcon = 0; - wc.lpszMenuName = 0; - wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW); - wc.style = CS_DBLCLKS; - wc.cbClsExtra = 0; - wc.cbWndExtra = sizeof( CtrlRegisterList * ); - wc.hIconSm = 0; - - - RegisterClassEx(&wc); + WNDCLASSEX wc; + + wc.cbSize = sizeof(wc); + wc.lpszClassName = szClassName; + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = CtrlRegisterList::wndProc; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hIcon = 0; + wc.lpszMenuName = 0; + wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW); + wc.style = CS_DBLCLKS; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(CtrlRegisterList *); + wc.hIconSm = 0; + + RegisterClassEx(&wc); } void CtrlRegisterList::deinit() @@ -53,8 +52,6 @@ void CtrlRegisterList::deinit() //UnregisterClass(szClassName, hInst) } - - LRESULT CALLBACK CtrlRegisterList::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { CtrlRegisterList *ccp = CtrlRegisterList::getFrom(hwnd); @@ -109,44 +106,30 @@ LRESULT CALLBACK CtrlRegisterList::wndProc(HWND hwnd, UINT msg, WPARAM wParam, L break; case WM_GETDLGCODE: // want chars so that we can return 0 on key press and supress the beeping sound return DLGC_WANTARROWS|DLGC_WANTCHARS; - default: - break; - } - - return DefWindowProc(hwnd, msg, wParam, lParam); -} + default: + break; + } + return DefWindowProc(hwnd, msg, wParam, lParam); +} CtrlRegisterList *CtrlRegisterList::getFrom(HWND hwnd) { - return (CtrlRegisterList *)GetWindowLongPtr(hwnd, GWLP_USERDATA); + return (CtrlRegisterList *)GetWindowLongPtr(hwnd, GWLP_USERDATA); } - - - CtrlRegisterList::CtrlRegisterList(HWND _wnd) -{ - wnd=_wnd; + : wnd(_wnd) { SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)this); - //SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd,GWL_STYLE) | WS_VSCROLL); - //SetScrollRange(wnd, SB_VERT, -1,1,TRUE); - - rowHeight=g_Config.iFontHeight; - font = CreateFont(rowHeight,g_Config.iFontWidth,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, - DEFAULT_QUALITY,DEFAULT_PITCH,L"Lucida Console"); - selecting=false; - selection=0; - category=0; - showHex=false; - cpu=0; - lastPC = 0; - lastCat0Values = NULL; - changedCat0Regs = NULL; + const float fontScale = 1.0f / g_dpi_scale_real_y; + rowHeight = g_Config.iFontHeight * fontScale; + int charWidth = g_Config.iFontWidth * fontScale; + font = CreateFont(rowHeight, charWidth, 0, 0, + FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, + L"Lucida Console"); } - CtrlRegisterList::~CtrlRegisterList() { DeleteObject(font); diff --git a/Windows/Debugger/CtrlRegisterList.h b/Windows/Debugger/CtrlRegisterList.h index fcaa78967e..123e8e0713 100644 --- a/Windows/Debugger/CtrlRegisterList.h +++ b/Windows/Debugger/CtrlRegisterList.h @@ -27,23 +27,23 @@ class CtrlRegisterList RECT rect; int rowHeight; - int selection; - int marker; - int category; + int selection = 0; + int marker = 0; + int category = 0; - int oldSelection; + int oldSelection = 0; - bool selectionChanged; - bool selecting; - bool hasFocus; - bool showHex; - DebugInterface *cpu; + bool selectionChanged = false; + bool selecting = false; + bool hasFocus = false; + bool showHex = false; + DebugInterface *cpu = nullptr; static TCHAR szClassName[]; - u32 lastPC; - u32 *lastCat0Values; - bool *changedCat0Regs; - bool ctrlDown; + u32 lastPC = 0; + u32 *lastCat0Values = nullptr; + bool *changedCat0Regs = nullptr; + bool ctrlDown = false; u32 getSelectedRegValue(char *out, size_t size); void copyRegisterValue(); @@ -79,4 +79,4 @@ public: { return cpu; } -}; \ No newline at end of file +}; From 12057532895be674d98c389d3d6dc78da90401f9 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 3 Mar 2019 17:50:54 -0800 Subject: [PATCH 42/81] UI: Pass touch/button releases to all screens. This way, if you go into a menu and release a button, it still gets noticed. This also goes for axis centering (and therefore vkeys.) Also, move TOUCH_RELEASE_ALL to all screen switches. --- UI/EmuScreen.cpp | 17 ------------ UI/EmuScreen.h | 2 -- UI/MainScreen.cpp | 7 ++++- ext/native/ui/screen.cpp | 58 +++++++++++++++++++++++++++++++--------- 4 files changed, 51 insertions(+), 33 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index dc19ce2977..d8a3fbc2d2 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -381,10 +381,7 @@ static void AfterStateBoot(SaveState::Status status, const std::string &message, void EmuScreen::sendMessage(const char *message, const char *value) { // External commands, like from the Windows UI. if (!strcmp(message, "pause") && screenManager()->topScreen() == this) { - releaseButtons(); screenManager()->push(new GamePauseScreen(gamePath_)); - } else if (!strcmp(message, "lost_focus")) { - releaseButtons(); } else if (!strcmp(message, "stop")) { // We will push MainScreen in update(). PSP_Shutdown(); @@ -420,15 +417,12 @@ void EmuScreen::sendMessage(const char *message, const char *value) { RecreateViews(); } else if (!strcmp(message, "control mapping") && screenManager()->topScreen() == this) { UpdateUIState(UISTATE_PAUSEMENU); - releaseButtons(); screenManager()->push(new ControlMappingScreen()); } else if (!strcmp(message, "display layout editor") && screenManager()->topScreen() == this) { UpdateUIState(UISTATE_PAUSEMENU); - releaseButtons(); screenManager()->push(new DisplayLayoutScreen()); } else if (!strcmp(message, "settings") && screenManager()->topScreen() == this) { UpdateUIState(UISTATE_PAUSEMENU); - releaseButtons(); screenManager()->push(new GameSettingsScreen(gamePath_)); } else if (!strcmp(message, "gpu dump next frame")) { if (gpu) @@ -1001,7 +995,6 @@ void EmuScreen::CreateViews() { } UI::EventReturn EmuScreen::OnDevTools(UI::EventParams ¶ms) { - releaseButtons(); I18NCategory *dev = GetI18NCategory("Developer"); DevMenu *devMenu = new DevMenu(dev); if (params.v) @@ -1060,7 +1053,6 @@ void EmuScreen::update() { // This is here to support the iOS on screen back button. if (pauseTrigger_) { pauseTrigger_ = false; - releaseButtons(); screenManager()->push(new GamePauseScreen(gamePath_)); } @@ -1374,15 +1366,6 @@ void EmuScreen::autoLoad() { } } -// TODO: Add generic loss-of-focus handling for Screens, use this. -void EmuScreen::releaseButtons() { - TouchInput input; - input.flags = TOUCH_RELEASE_ALL; - input.timestamp = time_now_d(); - input.id = 0; - touch(input); -} - void EmuScreen::resized() { RecreateViews(); } diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 0ac62e76e7..6951afad11 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -66,8 +66,6 @@ private: void setVKeyAnalogX(int stick, int virtualKeyMin, int virtualKeyMax); void setVKeyAnalogY(int stick, int virtualKeyMin, int virtualKeyMax); - void releaseButtons(); - void autoLoad(); void checkPowerDown(); diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index c6e4965b66..98e813d9ff 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -157,8 +157,12 @@ public: } } else if (hovering_ && key.deviceId == DEVICE_ID_MOUSE && key.keyCode == NKCODE_EXT_MOUSEBUTTON_2) { // If it's the right mouse button, and it's not otherwise mapped, show the info also. - if (key.flags & KEY_UP) { + if (key.flags & KEY_DOWN) { + showInfoPressed_ = true; + } + if ((key.flags & KEY_UP) && showInfoPressed_) { showInfo = true; + showInfoPressed_ = false; } } @@ -208,6 +212,7 @@ private: double holdStart_ = 0.0; bool holdEnabled_ = true; + bool showInfoPressed_ = false; bool hovering_ = false; }; diff --git a/ext/native/ui/screen.cpp b/ext/native/ui/screen.cpp index 9f88c02bb1..8d86f10a6b 100644 --- a/ext/native/ui/screen.cpp +++ b/ext/native/ui/screen.cpp @@ -1,5 +1,6 @@ #include "base/display.h" #include "base/logging.h" +#include "base/timeutil.h" #include "input/input_state.h" #include "ui/screen.h" #include "ui/ui.h" @@ -71,30 +72,46 @@ void ScreenManager::switchToNext() { bool ScreenManager::touch(const TouchInput &touch) { std::lock_guard guard(inputLock_); - if (!stack_.empty()) { + bool result = false; + // Send release all events to every screen layer. + if (touch.flags & TOUCH_RELEASE_ALL) { + for (auto &layer : stack_) { + Screen *screen = layer.screen; + result = layer.screen->touch(screen->transformTouch(touch)); + } + } else if (!stack_.empty()) { Screen *screen = stack_.back().screen; - return screen->touch(screen->transformTouch(touch)); - } else { - return false; + result = stack_.back().screen->touch(screen->transformTouch(touch)); } + return result; } bool ScreenManager::key(const KeyInput &key) { std::lock_guard guard(inputLock_); - if (!stack_.empty()) { - return stack_.back().screen->key(key); - } else { - return false; + bool result = false; + // Send key up to every screen layer. + if (key.flags & KEY_UP) { + for (auto &layer : stack_) { + result = layer.screen->key(key); + } + } else if (!stack_.empty()) { + result = stack_.back().screen->key(key); } + return result; } bool ScreenManager::axis(const AxisInput &axis) { std::lock_guard guard(inputLock_); - if (!stack_.empty()) { - return stack_.back().screen->axis(axis); - } else { - return false; + bool result = false; + // Send center axis to every screen layer. + if (axis.value == 0) { + for (auto &layer : stack_) { + result = layer.screen->axis(axis); + } + } else if (!stack_.empty()) { + result = stack_.back().screen->axis(axis); } + return result; } void ScreenManager::deviceLost() { @@ -158,6 +175,13 @@ void ScreenManager::render() { void ScreenManager::sendMessage(const char *msg, const char *value) { if (!strcmp(msg, "recreateviews")) RecreateAllViews(); + if (!strcmp(msg, "lost_focus")) { + TouchInput input; + input.flags = TOUCH_RELEASE_ALL; + input.timestamp = time_now_d(); + input.id = 0; + touch(input); + } if (!stack_.empty()) stack_.back().screen->sendMessage(msg, value); } @@ -188,7 +212,15 @@ void ScreenManager::push(Screen *screen, int layerFlags) { if (screen->isTransparent()) { layerFlags |= LAYER_TRANSPARENT; } - UI::SetFocusedView(0); + + // Release touches and unfocus. + UI::SetFocusedView(nullptr); + TouchInput input; + input.flags = TOUCH_RELEASE_ALL; + input.timestamp = time_now_d(); + input.id = 0; + touch(input); + Layer layer = {screen, layerFlags}; stack_.push_back(layer); } From 74282160639a29d14abbdb36ae7314d95d47cb16 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 3 Mar 2019 21:34:32 -0800 Subject: [PATCH 43/81] Windows: Clear help menu correctly. --- Windows/MainWindowMenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index b6ff2d0eac..d8249ab09d 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -93,7 +93,7 @@ namespace MainWindow { static void EmptySubMenu(HMENU menu) { int c = GetMenuItemCount(menu); for (int i = 0; i < c; ++i) { - RemoveMenu(menu, i, MF_BYPOSITION); + RemoveMenu(menu, 0, MF_BYPOSITION); } } From c821ad1d51071c5bbab369603969e749157262c5 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 3 Mar 2019 21:35:05 -0800 Subject: [PATCH 44/81] Windows: Link to https://. --- Windows/MainWindowMenu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index d8249ab09d..3c70a8d402 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -989,15 +989,15 @@ namespace MainWindow { break; case ID_HELP_OPENWEBSITE: - ShellExecute(NULL, L"open", L"http://www.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL); + ShellExecute(NULL, L"open", L"https://www.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL); break; case ID_HELP_BUYGOLD: - ShellExecute(NULL, L"open", L"http://central.ppsspp.org/buygold", NULL, NULL, SW_SHOWNORMAL); + ShellExecute(NULL, L"open", L"https://central.ppsspp.org/buygold", NULL, NULL, SW_SHOWNORMAL); break; case ID_HELP_OPENFORUM: - ShellExecute(NULL, L"open", L"http://forums.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL); + ShellExecute(NULL, L"open", L"https://forums.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL); break; case ID_HELP_GITHUB: From f2206158b2a9ccc3c0a98248d34f2f2148ef225b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 3 Mar 2019 21:39:21 -0800 Subject: [PATCH 45/81] UI: Update more browser links to https://. --- UI/MainScreen.cpp | 6 +++--- UI/ReportScreen.cpp | 4 ++-- Windows/GPU/WindowsGLContext.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index c6e4965b66..b86f4611df 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -802,10 +802,10 @@ void MainScreen::CreateViews() { scrollHomebrew->SetTag("MainScreenHomebrew"); GameBrowser *tabAllGames = new GameBrowser(g_Config.currentDirectory, true, &g_Config.bGridView2, - mm->T("How to get games"), "http://www.ppsspp.org/getgames.html", 0, + mm->T("How to get games"), "https://www.ppsspp.org/getgames.html", 0, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); GameBrowser *tabHomebrew = new GameBrowser(GetSysDirectory(DIRECTORY_GAME), false, &g_Config.bGridView3, - mm->T("How to get homebrew & demos", "How to get homebrew && demos"), "http://www.ppsspp.org/gethomebrew.html", + mm->T("How to get homebrew & demos", "How to get homebrew && demos"), "https://www.ppsspp.org/gethomebrew.html", FLAG_HOMEBREWSTOREBUTTON, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); @@ -1267,7 +1267,7 @@ void UmdReplaceScreen::CreateViews() { scrollAllGames->SetTag("UmdReplaceAllGames"); GameBrowser *tabAllGames = new GameBrowser(g_Config.currentDirectory, true, &g_Config.bGridView2, - mm->T("How to get games"), "http://www.ppsspp.org/getgames.html", 0, + mm->T("How to get games"), "https://www.ppsspp.org/getgames.html", 0, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); scrollAllGames->Add(tabAllGames); diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index 7901e92a44..43c50959ed 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -341,7 +341,7 @@ EventReturn ReportScreen::HandleSubmit(EventParams &e) { } EventReturn ReportScreen::HandleBrowser(EventParams &e) { - const std::string url = "http://" + Reporting::ServerHost() + "/"; + const std::string url = "https://" + Reporting::ServerHost() + "/"; LaunchBrowser(url.c_str()); return EVENT_DONE; } @@ -458,7 +458,7 @@ void ReportFinishScreen::ShowSuggestions() { } UI::EventReturn ReportFinishScreen::HandleViewFeedback(UI::EventParams &e) { - const std::string url = "http://" + Reporting::ServerHost() + "/game/" + Reporting::CurrentGameID(); + const std::string url = "https://" + Reporting::ServerHost() + "/game/" + Reporting::CurrentGameID(); LaunchBrowser(url.c_str()); return EVENT_DONE; } diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index e4851e6329..97540ec629 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -255,7 +255,7 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) { const char *defaultError = "Insufficient OpenGL driver support detected!\n\n" "Your GPU reports that it does not support OpenGL 2.0. Would you like to try using DirectX instead?\n\n" "DirectX is currently compatible with less games, but on your GPU it may be the only choice.\n\n" - "Visit the forums at http://forums.ppsspp.org for more information.\n\n"; + "Visit the forums at https://forums.ppsspp.org for more information.\n\n"; std::wstring versionDetected = ConvertUTF8ToWString(glVersion + "\n\n"); std::wstring error = ConvertUTF8ToWString(err->T("InsufficientOpenGLDriver", defaultError)); From 271389b8e5556d7531107be209d920b72e65df0a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 10 Mar 2019 08:35:31 -0700 Subject: [PATCH 46/81] GLES: Fix stencil buffer upload at > 1x PSP. Also fixes crashes on ATI. See #6627. --- GPU/Common/FramebufferCommon.cpp | 3 ++- GPU/Common/FramebufferCommon.h | 2 ++ GPU/GLES/StencilBufferGLES.cpp | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 51fb52b641..82fdf7d719 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -1863,7 +1863,8 @@ Draw::Framebuffer *FramebufferManagerCommon::GetTempFBO(TempFBO reason, u16 w, u } textureCache_->ForgetLastTexture(); - Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, false, depth }); + bool z_stencil = reason == TempFBO::STENCIL; + Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, z_stencil, depth }); if (!fbo) return fbo; diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index 9a954c1975..04d94388ce 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -162,6 +162,8 @@ enum class TempFBO { BLIT, // For copies of framebuffers (e.g. shader blending.) COPY, + // Used to copy stencil data, means we need a stencil backing. + STENCIL, }; inline Draw::DataFormat GEFormatToThin3D(int geFormat) { diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index 2e13c35885..76239b5282 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -168,7 +168,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe Draw::Framebuffer *blitFBO = nullptr; if (useBlit) { - blitFBO = GetTempFBO(TempFBO::COPY, w, h, Draw::FBO_8888); + blitFBO = GetTempFBO(TempFBO::STENCIL, w, h, Draw::FBO_8888); draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); } else if (dstBuffer->fbo) { draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::DONT_CARE }); From 7865589f4810e6a55d632a4d97a6e20510e6194b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 11 Mar 2019 12:55:09 +0100 Subject: [PATCH 47/81] sceFontLib: Don't call the callback if double-free. Should fix one part of #6627 --- Core/HLE/sceFont.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 1402a908ef..8a4ee5ed92 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -436,7 +436,9 @@ public: } u32 args[2] = { params_.userDataAddr, (u32)handle_ }; // TODO: The return value of this is leaking. - __KernelDirectMipsCall(params_.freeFuncAddr, 0, args, 2, false); + if (handle_) { // Avoid calling free-callback on double-free + __KernelDirectMipsCall(params_.freeFuncAddr, 0, args, 2, false); + } handle_ = 0; fonts_.clear(); isfontopen_.clear(); From 186584e087fd8e4b684b50763e5eb5b1c6ca1017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 11 Mar 2019 15:57:45 +0100 Subject: [PATCH 48/81] Update to a new gradle version again --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 62ec80d1ce..7b7c94e172 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.3.1' + classpath 'com.android.tools.build:gradle:3.3.2' } } From 3445f39f3f961097b338122d3f65a65fafcd6a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 11 Mar 2019 16:29:08 +0100 Subject: [PATCH 49/81] Survive pipeline creation failure on Vulkan. Makes Burnout playable on Pocophone... Sigh. Minor cleanups. --- GPU/GLES/ShaderManagerGLES.cpp | 2 +- GPU/Vulkan/PipelineManagerVulkan.cpp | 17 ++++++++++------- GPU/Vulkan/ShaderManagerVulkan.cpp | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index ffafcaa362..fc62801499 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -828,7 +828,7 @@ std::string ShaderManagerGLES::DebugGetShaderString(std::string id, DebugShaderT // as sometimes these features might have an effect on the ID bits. #define CACHE_HEADER_MAGIC 0x83277592 -#define CACHE_VERSION 13 +#define CACHE_VERSION 14 struct CacheHeader { uint32_t magic; uint32_t version; diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 27d513aa2c..278ea2f9e1 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -135,7 +135,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip PROFILE_THIS_SCOPE("pipelinebuild"); bool useBlendConstant = false; - VkPipelineColorBlendAttachmentState blend0 = {}; + VkPipelineColorBlendAttachmentState blend0{}; blend0.blendEnable = key.blendEnable; if (key.blendEnable) { blend0.colorBlendOp = (VkBlendOp)key.blendOpColor; @@ -174,7 +174,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip dss.depthWriteEnable = key.depthWriteEnable; } - VkDynamicState dynamicStates[8]; + VkDynamicState dynamicStates[8]{}; int numDyn = 0; if (key.blendEnable && (UsesBlendConstant(key.srcAlpha) || UsesBlendConstant(key.srcColor) || UsesBlendConstant(key.destAlpha) || UsesBlendConstant(key.destColor))) { @@ -208,16 +208,14 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip ms.pSampleMask = nullptr; ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - VkPipelineShaderStageCreateInfo ss[2]; + VkPipelineShaderStageCreateInfo ss[2]{}; ss[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - ss[0].pNext = nullptr; ss[0].stage = VK_SHADER_STAGE_VERTEX_BIT; ss[0].pSpecializationInfo = nullptr; ss[0].module = vs->GetModule(); ss[0].pName = "main"; ss[0].flags = 0; ss[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - ss[1].pNext = nullptr; ss[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; ss[1].pSpecializationInfo = nullptr; ss[1].module = fs->GetModule(); @@ -252,7 +250,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip vertexStride = 36; } - VkVertexInputBindingDescription ibd; + VkVertexInputBindingDescription ibd{}; ibd.binding = 0; ibd.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; ibd.stride = vertexStride; @@ -297,7 +295,12 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip VkPipeline pipeline; VkResult result = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipe, nullptr, &pipeline); if (result != VK_SUCCESS) { - _assert_msg_(G3D, false, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result)); + if (result == VK_INCOMPLETE) { + // Bad return value seen on Adreno in Burnout :( Try to ignore? + // TODO: Log all the information we can here! + } else { + _dbg_assert_msg_(G3D, false, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result)); + } ERROR_LOG(G3D, "Failed creating graphics pipeline! result='%s'", VulkanResultToString(result)); // Create a placeholder to avoid creating over and over if something is broken. VulkanPipeline *nullPipeline = new VulkanPipeline(); diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 43dd9de1ea..fadb94bdd4 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -361,7 +361,7 @@ VulkanFragmentShader *ShaderManagerVulkan::GetFragmentShaderFromModule(VkShaderM // instantaneous. #define CACHE_HEADER_MAGIC 0xff51f420 -#define CACHE_VERSION 16 +#define CACHE_VERSION 17 struct VulkanCacheHeader { uint32_t magic; uint32_t version; From 624587c594c48e2a9c9b38c2cc82348829934423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 11 Mar 2019 16:42:41 +0100 Subject: [PATCH 50/81] Fix a VK validation failure when opening the homebrew menu --- ext/native/thin3d/VulkanRenderManager.h | 3 +++ ext/native/ui/ui_context.cpp | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index a01482b69e..cfac32d75c 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -118,6 +118,7 @@ public: void SetViewport(const VkViewport &vp) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_(G3D, (int)vp.width >= 0); VkRenderData data{ VKRRenderCommand::VIEWPORT }; data.viewport.vp.x = vp.x; data.viewport.vp.y = vp.y; @@ -132,6 +133,8 @@ public: void SetScissor(const VkRect2D &rc) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_(G3D, (int)rc.extent.width >= 0); + _dbg_assert_(G3D, (int)rc.extent.height >= 0); VkRenderData data{ VKRRenderCommand::SCISSOR }; data.scissor.scissor = rc; curRenderStep_->commands.push_back(data); diff --git a/ext/native/ui/ui_context.cpp b/ext/native/ui/ui_context.cpp index 0106888ec4..b5f7ba204f 100644 --- a/ext/native/ui/ui_context.cpp +++ b/ext/native/ui/ui_context.cpp @@ -1,4 +1,7 @@ #include "ppsspp_config.h" + +#include + #include "base/display.h" #include "ui/ui.h" #include "ui/view.h" @@ -111,8 +114,8 @@ void UIContext::ActivateTopScissor() { bounds = scissorStack_.back(); int x = floorf(scale_x * bounds.x); int y = floorf(scale_y * bounds.y); - int w = ceilf(scale_x * bounds.w); - int h = ceilf(scale_y * bounds.h); + int w = std::max(0.0f, ceilf(scale_x * bounds.w)); + int h = std::max(0.0f, ceilf(scale_y * bounds.h)); draw_->SetScissorRect(x, y, w, h); } else { // Avoid rounding errors From 60e32e914ec74520af2f20afe3af00707da33424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 12 Mar 2019 09:33:39 +0100 Subject: [PATCH 51/81] Fix apparent bug in #11094, fixes #11878 and likely #11798 --- Core/HLE/sceCtrl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index 1b552a4191..6074b1601f 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -1,4 +1,3 @@ - // Copyright (c) 2012- PPSSPP Project. // This program is free software: you can redistribute it and/or modify @@ -509,7 +508,7 @@ static void __CtrlWriteUserLatch(CtrlLatch *userLatch, int bufs) { userLatch->btnMake &= CTRL_MASK_USER; userLatch->btnPress &= CTRL_MASK_USER; if (bufs > 0) { - userLatch->btnRelease |= CTRL_MASK_USER; + userLatch->btnRelease |= ~CTRL_MASK_USER; } } From 7362cccee4d1e52f505ea89fa4b81e73752c6a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 12 Mar 2019 22:34:41 +0100 Subject: [PATCH 52/81] Vulkan subpass dependencies: Handle VK_IMAGE_LAYOUT_UNDEFINED without debug-asserting. --- ext/native/thin3d/VulkanQueueRunner.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 4de46705be..9ca8d67efc 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -249,6 +249,9 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { VkSubpassDependency deps[2]{}; int numDeps = 0; switch (key.prevColorLayout) { + case VK_IMAGE_LAYOUT_UNDEFINED: + // No need to specify stage or access. + break; case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: // Already the right color layout. Unclear that we need to do a lot here.. break; @@ -275,6 +278,9 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { } switch (key.prevDepthLayout) { + case VK_IMAGE_LAYOUT_UNDEFINED: + // No need to specify stage or access. + break; case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: // Already the right depth layout. Unclear that we need to do a lot here.. break; From 55ccc4ed81fbac82540d88629c44e9530f91e618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 13 Mar 2019 11:24:23 +0100 Subject: [PATCH 53/81] On game load error screens, print the filename. May help diagnose issues from screenshots of the error (commonly sent by end-users) --- UI/EmuScreen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index dc19ce2977..620ca33143 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1040,8 +1040,8 @@ void EmuScreen::update() { return; } I18NCategory *err = GetI18NCategory("Error"); - std::string errLoadingFile = err->T("Error loading file", "Could not load game"); - + std::string errLoadingFile = gamePath_ + "\n"; + errLoadingFile.append(err->T("Error loading file", "Could not load game")); errLoadingFile.append(" "); errLoadingFile.append(err->T(errorMessage_.c_str())); From 786914690dc68109e42444a613ee68161b6f9692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 13 Mar 2019 11:37:52 +0100 Subject: [PATCH 54/81] Temporary commit to get CalcCullRange logging into a buildbot build --- GPU/Common/ShaderUniforms.cpp | 39 ++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index 46ad4470e2..e8138f7df3 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -77,16 +77,39 @@ void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bo auto y = sortPair(reverseViewportY(0.0f), reverseViewportY(4096.0f)); auto z = sortPair(reverseViewportZ(0.0f), reverseViewportZ(65535.5f)); // Since we have space in w, use it to pass the depth clamp flag. We also pass NAN for w "discard". + // Note: The clampEnable flag here is currently not used by the shader. float clampEnable = gstate.isDepthClampEnabled() ? 1.0f : 0.0f; - minValues[0] = x.first; - minValues[1] = y.first; - minValues[2] = z.first; - minValues[3] = clampEnable; - maxValues[0] = x.second; - maxValues[1] = y.second; - maxValues[2] = z.second; - maxValues[3] = NAN; + float minVal[4]; + float maxVal[4]; + + minVal[0] = x.first; + minVal[1] = y.first; + minVal[2] = z.first; + minVal[3] = clampEnable; + maxVal[0] = x.second; + maxVal[1] = y.second; + maxVal[2] = z.second; + maxVal[3] = NAN; + + auto CopyFour = [](float dst[4], float src[4]) { + bool changed = false; + for (int i = 0; i < 4; i++) { + // NAN-compatible checking + if (memcmp(&dst[i], &src[i], 4) != 0) { + if (i < 3) + changed = true; + dst[i] = src[i]; + } + } + return changed; + }; + bool changedMin = CopyFour(minValues, minVal); + bool changedMax = CopyFour(maxValues, maxVal); + if (changedMin || changedMax) { + WLOG("ClampMin: %f %f %f %f", minVal[0], minVal[1], minVal[2], minVal[3]); + WLOG("ClampMax: %f %f %f %f", maxVal[0], maxVal[1], maxVal[2], maxVal[3]); + } } void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipViewport) { From f316a65905db62c1a20eadd60c03c8db27d49087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 13 Mar 2019 11:39:08 +0100 Subject: [PATCH 55/81] Revert "Temporary commit to get CalcCullRange logging into a buildbot build" This reverts commit 786914690dc68109e42444a613ee68161b6f9692. --- GPU/Common/ShaderUniforms.cpp | 39 +++++++---------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index e8138f7df3..46ad4470e2 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -77,39 +77,16 @@ void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bo auto y = sortPair(reverseViewportY(0.0f), reverseViewportY(4096.0f)); auto z = sortPair(reverseViewportZ(0.0f), reverseViewportZ(65535.5f)); // Since we have space in w, use it to pass the depth clamp flag. We also pass NAN for w "discard". - // Note: The clampEnable flag here is currently not used by the shader. float clampEnable = gstate.isDepthClampEnabled() ? 1.0f : 0.0f; - float minVal[4]; - float maxVal[4]; - - minVal[0] = x.first; - minVal[1] = y.first; - minVal[2] = z.first; - minVal[3] = clampEnable; - maxVal[0] = x.second; - maxVal[1] = y.second; - maxVal[2] = z.second; - maxVal[3] = NAN; - - auto CopyFour = [](float dst[4], float src[4]) { - bool changed = false; - for (int i = 0; i < 4; i++) { - // NAN-compatible checking - if (memcmp(&dst[i], &src[i], 4) != 0) { - if (i < 3) - changed = true; - dst[i] = src[i]; - } - } - return changed; - }; - bool changedMin = CopyFour(minValues, minVal); - bool changedMax = CopyFour(maxValues, maxVal); - if (changedMin || changedMax) { - WLOG("ClampMin: %f %f %f %f", minVal[0], minVal[1], minVal[2], minVal[3]); - WLOG("ClampMax: %f %f %f %f", maxVal[0], maxVal[1], maxVal[2], maxVal[3]); - } + minValues[0] = x.first; + minValues[1] = y.first; + minValues[2] = z.first; + minValues[3] = clampEnable; + maxValues[0] = x.second; + maxValues[1] = y.second; + maxValues[2] = z.second; + maxValues[3] = NAN; } void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipViewport) { From 536d61796a45ea48564c154e1d1db3f9038b8683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 13 Mar 2019 14:15:52 +0100 Subject: [PATCH 56/81] Android (and libretro): Turn off -ffast-math. Fixes #11880. --- CMakeLists.txt | 2 -- libretro/jni/Android.mk | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ba13db8cf..1d443e1ee8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -270,8 +270,6 @@ if(NOT MSVC) add_compile_options(-fno-strict-aliasing) if(${CMAKE_C_COMPILER_ID} STREQUAL "Intel") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -parallel -fopenmp") - else() - add_compile_options(-ffast-math) endif() if(X86 OR X86_64) diff --git a/libretro/jni/Android.mk b/libretro/jni/Android.mk index 5e4ae68400..e9b773c024 100644 --- a/libretro/jni/Android.mk +++ b/libretro/jni/Android.mk @@ -74,7 +74,7 @@ include $(CORE_DIR)/libretro/Makefile.common COREFLAGS += -DINLINE="inline" -DPPSSPP -DUSE_FFMPEG -DMOBILE_DEVICE -DBAKE_IN_GIT -DDYNAREC -D__LIBRETRO__ -DUSING_GLES2 -D__STDC_CONSTANT_MACROS -DGLEW_NO_GLU $(INCFLAGS) LOCAL_SRC_FILES = $(SOURCES_CXX) $(SOURCES_C) $(ASMFILES) LOCAL_CPPFLAGS := -Wall -std=gnu++11 $(COREFLAGS) -DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS -LOCAL_CFLAGS := -O2 -ffast-math -DANDROID $(COREFLAGS) +LOCAL_CFLAGS := -O2 -DANDROID $(COREFLAGS) LOCAL_LDLIBS += -lz -llog -lGLESv2 -lEGL -latomic LOCAL_STATIC_LIBRARIES += $(FFMPEGLIBS) From c629299c08d03a5033153c9f0a5cde109ffb5844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 2 Mar 2019 20:27:03 +0100 Subject: [PATCH 57/81] Update README.md for 1.8.0. Thanks unknown for collecting, I've resorted it a bit. --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 1f7df22625..af4bef3711 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,35 @@ For build instructions and other development tutorials, see [the wiki](https://g For game compatibility, see [community compatibility feedback](https://report.ppsspp.org/games). +What's new in 1.8.0 +------------------- +* Avoid crash when starting PPSSPP due to bad AMD Vulkan drivers (#11802) +* PowerVR Vulkan display corruption fixed (#11744, #11747) +* Naruto Shippuden 3 hang fixed (#11780) +* Fixes to various lighting bugs (#11567, #11574, #11577) +* Significant performance improvement in Earth Defense Force 2 (#11172) +* Fix "real clock sync" setting (helps with latency for music games - #11813) +* More speed in FF4 effects and other generated curves (#11425) +* Support for resizing Vulkan on Linux (#11451) +* Improved support for GLES on Linux/IoT (#11507, #11537, #11541, #11632, #11746, #11806, #11845) +* Percentage based frameskipping (#11523) +* DXT accuracy improved, fixing thick white line in Gran Turismo sky (#11530) +* Fix Motorstorm freeze on non-Windows (#11618) +* Faster block transfer in some games like Digimon Adventures (#11531, #11553, #11776) +* Blending optimizations and improvements (#11543, #11620) +* Improve D3D11 rendering issues (#11584) +* Change default graphics backend to D3D11 or OpenGL (#11621, #11658) +* Remove some outdated settings (#11665, #11666, #11667) +* Fix remote disc streaming with ipv6 (#11689, #11700) +* Vulkan: Workarounds for some driver bugs for 5xx series Qualcomm GPUs (#11691, #11694) +* Fix some Qt port issues with recent performance improvements (#11720, #11807, #11808) +* UWP Xbox One: fix X/Back button confusion (#11740) +* Fix Formula 1 2006 timing issue (#11767) +* Fixes and workarounds for some vertex range culling bugs that broke a few games (#11785, #11859), and disable it on older GPUs (#11712, #11773, #11787) +* Android: Allow putting PSP storage on custom paths like SD cards (#11812) +* Corrected vocp instruction, fixing models in Artdink games (#11822, #11835) +* Bundle SDL in binary for macOS builds (#11831) +* Prevent keeping games open on Windows (#11842) What's new in 1.7.3/1.7.4/1.7.5 ------------------- From 29b26ce91872a36a084d057acbf0ad63ea6a4a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 13 Mar 2019 16:49:29 +0100 Subject: [PATCH 58/81] Add last minute fix mention --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index af4bef3711..024ecdcaa4 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ What's new in 1.8.0 * PowerVR Vulkan display corruption fixed (#11744, #11747) * Naruto Shippuden 3 hang fixed (#11780) * Fixes to various lighting bugs (#11567, #11574, #11577) +* Fix control issue in Sonic Rivals and Rock Band (#11878, #11798, #11879) * Significant performance improvement in Earth Defense Force 2 (#11172) * Fix "real clock sync" setting (helps with latency for music games - #11813) * More speed in FF4 effects and other generated curves (#11425) From 1bedb97bc41fd056ed20fe02658910a4e7bec3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 13 Mar 2019 16:54:50 +0100 Subject: [PATCH 59/81] Update the lang submodule --- assets/lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lang b/assets/lang index f97aa5d000..18e0d460e1 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit f97aa5d000b0a27e27b88b0072ccf932de506eae +Subproject commit 18e0d460e187556e9510e2e9b5ae85fa435cefd9 From e66f019ffaaf7ff4224aa3605ebf59f5654bd0d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 14 Mar 2019 09:00:50 +0100 Subject: [PATCH 60/81] Update the version number in AndroidManifest.xml (pretty sure we don't really still need to do this, but whatever). --- android/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index c9e9cf2050..07237cd121 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="18000000" + android:versionName="1.8.0.0"> From 4d5af330a7b11ca32003350efb6b0178fe9b0d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 14 Mar 2019 10:59:11 +0100 Subject: [PATCH 61/81] Windows: Change FP model to Precise. See #11384 --- Common/Common.vcxproj | 8 ++++---- Core/Core.vcxproj | 8 ++++---- GPU/GPU.vcxproj | 10 +++++----- Windows/PPSSPP.vcxproj | 10 +++++----- ext/libkirk/libkirk.vcxproj | 6 +++--- ext/native/native.vcxproj | 10 +++++----- ext/zlib/zlib.vcxproj | 10 +++++----- headless/Headless.vcxproj | 12 ++++++------ 8 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 5f4fa1688e..6200675522 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -76,7 +76,7 @@ MultiThreadedDebug ../ext/native;../ext/snappy;.. StreamingSIMDExtensions2 - Fast + Precise true false false @@ -103,7 +103,7 @@ _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) ../ext/native;../ext/snappy;.. NotSet - Fast + Precise false true false @@ -133,7 +133,7 @@ stdafx.h false StreamingSIMDExtensions2 - Fast + Precise ../ext/native;../ext/snappy;.. Speed true @@ -166,7 +166,7 @@ ../ext/native;../ext/snappy;.. false NotSet - Fast + Precise Speed false true diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 34d117cf66..51af34e22f 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -73,7 +73,7 @@ ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) StreamingSIMDExtensions2 - Fast + Precise true false false @@ -95,7 +95,7 @@ ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) NotSet - Fast + Precise false true false @@ -121,7 +121,7 @@ ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext false StreamingSIMDExtensions2 - Fast + Precise USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_LIB;NDEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) Speed MultiThreaded @@ -150,7 +150,7 @@ true ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext NotSet - Fast + Precise false false Speed diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 13264c837c..9354e28bc5 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -88,7 +88,7 @@ ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy; _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) StreamingSIMDExtensions2 - Fast + Precise true false false @@ -109,7 +109,7 @@ Level3 ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy; NotSet - Fast + Precise false true false @@ -136,7 +136,7 @@ ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy; false StreamingSIMDExtensions2 - Fast + Precise USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_LIB;NDEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) Speed true @@ -162,7 +162,7 @@ ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy; false NotSet - Fast + Precise Speed false true @@ -390,4 +390,4 @@ - \ No newline at end of file + diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index 9945c91e62..27a423df46 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -130,7 +130,7 @@ stdafx.h;Common/DbgNew.h MultiThreadedDebug StreamingSIMDExtensions2 - Fast + Precise true false Disabled @@ -168,7 +168,7 @@ MultiThreadedDebug false NotSet - Fast + Precise true false Disabled @@ -199,7 +199,7 @@ MultiThreaded false StreamingSIMDExtensions2 - Fast + Precise Use Level3 ProgramDatabase @@ -248,7 +248,7 @@ MultiThreaded false NotSet - Fast + Precise Use Level3 ProgramDatabase @@ -587,4 +587,4 @@ - \ No newline at end of file + diff --git a/ext/libkirk/libkirk.vcxproj b/ext/libkirk/libkirk.vcxproj index bdaa0b01c3..036c3f9f68 100644 --- a/ext/libkirk/libkirk.vcxproj +++ b/ext/libkirk/libkirk.vcxproj @@ -70,7 +70,7 @@ Level3 - EnableFastChecks + EnablePreciseChecks _CRTDBG_MAP_ALLOC;_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS true false @@ -107,7 +107,7 @@ true false StreamingSIMDExtensions2 - Fast + Precise _MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS Speed true @@ -160,4 +160,4 @@ - \ No newline at end of file + diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 405888b732..ba5a926d8b 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -131,7 +131,7 @@ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); StreamingSIMDExtensions2 - Fast + Precise true false MultiThreaded @@ -158,7 +158,7 @@ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); NotSet - Fast + Precise true false MultiThreaded @@ -337,9 +337,9 @@ Speed false StreamingSIMDExtensions2 - Fast + Precise StreamingSIMDExtensions2 - Fast + Precise MaxSpeed MaxSpeed Default @@ -773,4 +773,4 @@ - \ No newline at end of file + diff --git a/ext/zlib/zlib.vcxproj b/ext/zlib/zlib.vcxproj index 81d64dcaae..6595864711 100644 --- a/ext/zlib/zlib.vcxproj +++ b/ext/zlib/zlib.vcxproj @@ -105,7 +105,7 @@ Level3 _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) StreamingSIMDExtensions2 - Fast + Precise Default true false @@ -127,7 +127,7 @@ _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) false NotSet - Fast + Precise Default true false @@ -152,7 +152,7 @@ _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) StreamingSIMDExtensions2 false - Fast + Precise Speed AnySuitable true @@ -180,7 +180,7 @@ Speed false NotSet - Fast + Precise true false MultiThreaded @@ -196,4 +196,4 @@ - \ No newline at end of file + diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index 5be939c78c..807a5a2856 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -94,9 +94,9 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_32=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS ../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native - EnableFastChecks + EnablePreciseChecks StreamingSIMDExtensions2 - Fast + Precise true false false @@ -127,7 +127,7 @@ _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) ../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native NotSet - Fast + Precise false true false @@ -162,7 +162,7 @@ ../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native false StreamingSIMDExtensions2 - Fast + Precise Speed true false @@ -196,7 +196,7 @@ ../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native false NotSet - Fast + Precise Speed false true @@ -281,4 +281,4 @@ - \ No newline at end of file + From 036aeda512165454803e806c2dcab3c7a56e9705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 14 Mar 2019 11:43:44 +0100 Subject: [PATCH 62/81] Correctly handle memory types in VulkanPushBuffer. Should help #11882. --- Common/Vulkan/VulkanMemory.cpp | 29 +++++++++++++---------------- Common/Vulkan/VulkanMemory.h | 3 +-- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index 2b13be2e01..1c87d945aa 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -23,9 +23,7 @@ #include "base/timeutil.h" #include "math/math_util.h" -VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size) : device_(vulkan->GetDevice()), buf_(0), offset_(0), size_(size), writePtr_(nullptr) { - vulkan->MemoryTypeFromProperties(0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &memoryTypeIndex_); - +VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size) : vulkan_(vulkan), buf_(0), offset_(0), size_(size), writePtr_(nullptr) { bool res = AddBuffer(); assert(res); } @@ -36,6 +34,7 @@ VulkanPushBuffer::~VulkanPushBuffer() { bool VulkanPushBuffer::AddBuffer() { BufInfo info; + VkDevice device = vulkan_->GetDevice(); VkBufferCreateInfo b{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; b.size = size_; @@ -45,34 +44,32 @@ bool VulkanPushBuffer::AddBuffer() { b.queueFamilyIndexCount = 0; b.pQueueFamilyIndices = nullptr; - VkResult res = vkCreateBuffer(device_, &b, nullptr, &info.buffer); + VkResult res = vkCreateBuffer(device, &b, nullptr, &info.buffer); if (VK_SUCCESS != res) { _assert_msg_(G3D, false, "vkCreateBuffer failed! result=%d", (int)res); return false; } - // Make validation happy. + // Get the buffer memory requirements. None of this can be cached! VkMemoryRequirements reqs; - vkGetBufferMemoryRequirements(device_, info.buffer, &reqs); - // TODO: We really should use memoryTypeIndex here.. + vkGetBufferMemoryRequirements(device, info.buffer, &reqs); // Okay, that's the buffer. Now let's allocate some memory for it. VkMemoryAllocateInfo alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; - // TODO: Should check here that memoryTypeIndex_ matches reqs.memoryTypeBits. - alloc.memoryTypeIndex = memoryTypeIndex_; alloc.allocationSize = reqs.size; + vulkan_->MemoryTypeFromProperties(0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &alloc.memoryTypeIndex); - res = vkAllocateMemory(device_, &alloc, nullptr, &info.deviceMemory); + res = vkAllocateMemory(device, &alloc, nullptr, &info.deviceMemory); if (VK_SUCCESS != res) { _assert_msg_(G3D, false, "vkAllocateMemory failed! size=%d result=%d", (int)reqs.size, (int)res); - vkDestroyBuffer(device_, info.buffer, nullptr); + vkDestroyBuffer(device, info.buffer, nullptr); return false; } - res = vkBindBufferMemory(device_, info.buffer, info.deviceMemory, 0); + res = vkBindBufferMemory(device, info.buffer, info.deviceMemory, 0); if (VK_SUCCESS != res) { ELOG("vkBindBufferMemory failed! result=%d", (int)res); - vkFreeMemory(device_, info.deviceMemory, nullptr); - vkDestroyBuffer(device_, info.buffer, nullptr); + vkFreeMemory(device, info.deviceMemory, nullptr); + vkDestroyBuffer(device, info.buffer, nullptr); return false; } @@ -137,7 +134,7 @@ size_t VulkanPushBuffer::GetTotalSize() const { void VulkanPushBuffer::Map() { _dbg_assert_(G3D, !writePtr_); - VkResult res = vkMapMemory(device_, buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_)); + VkResult res = vkMapMemory(vulkan_->GetDevice(), buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_)); _dbg_assert_(G3D, writePtr_); assert(VK_SUCCESS == res); } @@ -152,7 +149,7 @@ void VulkanPushBuffer::Unmap() { range.memory = buffers_[buf_].deviceMemory; vkFlushMappedMemoryRanges(device_, 1, &range); */ - vkUnmapMemory(device_, buffers_[buf_].deviceMemory); + vkUnmapMemory(vulkan_->GetDevice(), buffers_[buf_].deviceMemory); writePtr_ = nullptr; } diff --git a/Common/Vulkan/VulkanMemory.h b/Common/Vulkan/VulkanMemory.h index ef14de80ed..b43e0fe1af 100644 --- a/Common/Vulkan/VulkanMemory.h +++ b/Common/Vulkan/VulkanMemory.h @@ -108,12 +108,11 @@ private: void NextBuffer(size_t minSize); void Defragment(VulkanContext *vulkan); - VkDevice device_; + VulkanContext *vulkan_; std::vector buffers_; size_t buf_; size_t offset_; size_t size_; - uint32_t memoryTypeIndex_; uint8_t *writePtr_; }; From 06b04f65a00ee9a4fafabc943258db4bda2266c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 13 Mar 2019 23:31:54 +0100 Subject: [PATCH 63/81] Vulkan: Narrow down buffer usage flags a little bit. --- Common/Vulkan/VulkanMemory.cpp | 5 +++-- Common/Vulkan/VulkanMemory.h | 11 ++++++----- GPU/Vulkan/DrawEngineVulkan.cpp | 12 +++++++----- GPU/Vulkan/GPU_Vulkan.cpp | 3 ++- ext/native/thin3d/thin3d_vulkan.cpp | 3 ++- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index 1c87d945aa..7c5de4cd7f 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -23,7 +23,8 @@ #include "base/timeutil.h" #include "math/math_util.h" -VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size) : vulkan_(vulkan), buf_(0), offset_(0), size_(size), writePtr_(nullptr) { +VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage) + : vulkan_(vulkan), size_(size), usage_(usage) { bool res = AddBuffer(); assert(res); } @@ -39,7 +40,7 @@ bool VulkanPushBuffer::AddBuffer() { VkBufferCreateInfo b{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; b.size = size_; b.flags = 0; - b.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + b.usage = usage_; b.sharingMode = VK_SHARING_MODE_EXCLUSIVE; b.queueFamilyIndexCount = 0; b.pQueueFamilyIndices = nullptr; diff --git a/Common/Vulkan/VulkanMemory.h b/Common/Vulkan/VulkanMemory.h index b43e0fe1af..50e7017eb9 100644 --- a/Common/Vulkan/VulkanMemory.h +++ b/Common/Vulkan/VulkanMemory.h @@ -22,7 +22,7 @@ class VulkanPushBuffer { }; public: - VulkanPushBuffer(VulkanContext *vulkan, size_t size); + VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage); ~VulkanPushBuffer(); void Destroy(VulkanContext *vulkan); @@ -110,10 +110,11 @@ private: VulkanContext *vulkan_; std::vector buffers_; - size_t buf_; - size_t offset_; - size_t size_; - uint8_t *writePtr_; + size_t buf_ = 0; + size_t offset_ = 0; + size_t size_ = 0; + uint8_t *writePtr_ = nullptr; + VkBufferUsageFlags usage_; }; // VulkanDeviceAllocator diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index a2a9737a31..82c2656c84 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -148,9 +148,11 @@ void DrawEngineVulkan::InitDeviceObjects() { // if creating and updating them turns out to be expensive. for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { // We now create descriptor pools on demand, so removed from here. - frame_[i].pushUBO = new VulkanPushBuffer(vulkan_, 8 * 1024 * 1024); - frame_[i].pushVertex = new VulkanPushBuffer(vulkan_, 2 * 1024 * 1024); - frame_[i].pushIndex = new VulkanPushBuffer(vulkan_, 1 * 1024 * 1024); + // Note that pushUBO is also used for tessellation data (search for SetPushBuffer), and to upload + // the null texture. This should be cleaned up... + frame_[i].pushUBO = new VulkanPushBuffer(vulkan_, 8 * 1024 * 1024, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + frame_[i].pushVertex = new VulkanPushBuffer(vulkan_, 2 * 1024 * 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + frame_[i].pushIndex = new VulkanPushBuffer(vulkan_, 1 * 1024 * 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); } VkPipelineLayoutCreateInfo pl{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; @@ -174,7 +176,7 @@ void DrawEngineVulkan::InitDeviceObjects() { res = vkCreateSampler(device, &samp, nullptr, &nullSampler_); assert(VK_SUCCESS == res); - vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE); + vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); tessDataTransferVulkan = new TessellationDataTransferVulkan(vulkan_); tessDataTransfer = tessDataTransferVulkan; @@ -276,7 +278,7 @@ void DrawEngineVulkan::BeginFrame() { if (vertexCache_->GetTotalSize() > VERTEX_CACHE_SIZE) { vertexCache_->Destroy(vulkan_); delete vertexCache_; // orphans the buffers, they'll get deleted once no longer used by an in-flight frame. - vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE); + vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); vai_.Clear(); } diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index ca9f0d273b..18f6c1b6c0 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -463,7 +463,8 @@ void GPU_Vulkan::InitDeviceObjects() { // Initialize framedata for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { assert(!frameData_[i].push_); - frameData_[i].push_ = new VulkanPushBuffer(vulkan_, 64 * 1024); + VkBufferUsageFlags usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + frameData_[i].push_ = new VulkanPushBuffer(vulkan_, 64 * 1024, usage); } VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 17dda0da30..1479a7367b 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -814,7 +814,8 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) p.queueFamilyIndex = vulkan->GetGraphicsQueueFamilyIndex(); for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { - frame_[i].pushBuffer = new VulkanPushBuffer(vulkan_, 1024 * 1024); + VkBufferUsageFlags usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + frame_[i].pushBuffer = new VulkanPushBuffer(vulkan_, 1024 * 1024, usage); VkResult res = vkCreateDescriptorPool(device_, &dp, nullptr, &frame_[i].descriptorPool); _assert_(res == VK_SUCCESS); } From d6d6dbb772ad71ced8ffb2f69f9e6e2af1b10414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 14 Mar 2019 15:15:13 +0100 Subject: [PATCH 64/81] Finish up the fix attempt for #11882 --- Common/Vulkan/VulkanMemory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index 1c87d945aa..b6bb4b66ef 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -57,7 +57,7 @@ bool VulkanPushBuffer::AddBuffer() { // Okay, that's the buffer. Now let's allocate some memory for it. VkMemoryAllocateInfo alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; alloc.allocationSize = reqs.size; - vulkan_->MemoryTypeFromProperties(0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &alloc.memoryTypeIndex); + vulkan_->MemoryTypeFromProperties(reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &alloc.memoryTypeIndex); res = vkAllocateMemory(device, &alloc, nullptr, &info.deviceMemory); if (VK_SUCCESS != res) { From 0b48c6d066540021b047c657fd32a54b19c62a98 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 16 Mar 2019 19:40:33 -0700 Subject: [PATCH 65/81] SoftGPU: Apply color doubling only to RGB. Broken in #11379 - accidentally applied to the alpha value. See #11901 for an example where this caused issues with blending. --- GPU/Software/Rasterizer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 3b04e93396..27783c86d3 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -562,7 +562,8 @@ static inline Vec4 GetTextureFunctionOutput(const Vec4& prim_color, co const __m128 b = _mm_mul_ps(p, t); if (gstate.isColorDoublingEnabled()) { // We double right here, only for modulate. Other tex funcs do not color double. - out_rgb.ivec = _mm_cvtps_epi32(_mm_mul_ps(b, _mm_set_ps1(2.0f / 255.0f))); + const __m128 doubleColor = _mm_setr_ps(2.0f / 255.0f, 2.0f / 255.0f, 2.0f / 255.0f, 1.0f / 255.0f); + out_rgb.ivec = _mm_cvtps_epi32(_mm_mul_ps(b, doubleColor)); } else { out_rgb.ivec = _mm_cvtps_epi32(_mm_mul_ps(b, _mm_set_ps1(1.0f / 255.0f))); } From c5b844cc98bd544dd0fda68309be0b9bf4436393 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 16 Mar 2019 19:42:18 -0700 Subject: [PATCH 66/81] GPU: Respect stencil write mask on clear. Actually identified this for the softgpu in #11319, but applying it for RGBA is a problem in most renderers. Forgot to at least apply it to stencil. Fixes #11901. --- GPU/Common/GPUStateUtils.cpp | 2 +- GPU/Common/SoftwareTransformCommon.cpp | 4 +++- GPU/D3D11/StateMappingD3D11.cpp | 3 ++- GPU/Directx9/StateMappingDX9.cpp | 2 +- GPU/GLES/StateMappingGLES.cpp | 2 +- GPU/Vulkan/StateMappingVulkan.cpp | 3 ++- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 92b1d5f974..e26498ae91 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -1343,7 +1343,7 @@ void ConvertStencilFuncState(GenericStencilFuncState &state) { return; // The PSP's mask is reversed (bits not to write.) - state.writeMask = (~gstate.pmska) & 0xFF; + state.writeMask = (~gstate.getStencilWriteMask()) & 0xFF; state.sFail = gstate.getStencilOpSFail(); state.zFail = gstate.getStencilOpZFail(); diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index 4a77731f00..21d45951f7 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -457,7 +457,9 @@ void SoftwareTransform( // If alpha is not allowed to be separate, it must match for both depth/stencil and color. Vulkan requires this. bool alphaMatchesColor = gstate.isClearModeColorMask() == gstate.isClearModeAlphaMask(); bool depthMatchesStencil = gstate.isClearModeAlphaMask() == gstate.isClearModeDepthMask(); - if (params->allowSeparateAlphaClear || (alphaMatchesColor && depthMatchesStencil)) { + bool matchingComponents = params->allowSeparateAlphaClear || (alphaMatchesColor && depthMatchesStencil); + bool stencilNotMasked = !gstate.isClearModeAlphaMask() || gstate.getStencilWriteMask() == 0x00; + if (matchingComponents && stencilNotMasked) { result->color = transformed[1].color0_32; // Need to rescale from a [0, 1] float. This is the final transformed value. result->depth = ToScaledDepthFromIntegerScale((int)(transformed[1].z * 65535.0f)); diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index 0dc7a74e4b..9048330af4 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -330,7 +330,8 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { // A normal clear will be 2 points, the second point has the color. // We override this value in the pipeline from software transform for clear rectangles. dynState_.stencilRef = 0xFF; - keys_.depthStencil.stencilWriteMask = 0xFF; + // But we still apply the stencil write mask. + keys_.depthStencil.stencilWriteMask = (~gstate.getStencilWriteMask()) & 0xFF; } else { keys_.depthStencil.stencilTestEnable = false; dynState_.useStencil = false; diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 4e46ecdff4..9afb204704 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -233,7 +233,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) { dxstate.stencilTest.enable(); dxstate.stencilOp.set(D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE); dxstate.stencilFunc.set(D3DCMP_ALWAYS, 255, 0xFF); - dxstate.stencilMask.set(0xFF); + dxstate.stencilMask.set((~gstate.getStencilWriteMask()) & 0xFF); } else { dxstate.stencilTest.disable(); } diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index e6636b87e2..a630a5d6ef 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -277,7 +277,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) { framebufferManager_->SetDepthUpdated(); } renderManager->SetStencilFunc(gstate.isClearModeAlphaMask(), GL_ALWAYS, 0xFF, 0xFF); - renderManager->SetStencilOp(0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE); + renderManager->SetStencilOp((~gstate.getStencilWriteMask()) & 0xFF, GL_REPLACE, GL_REPLACE, GL_REPLACE); renderManager->SetDepth(true, gstate.isClearModeDepthMask() ? true : false, GL_ALWAYS); } else { // Depth Test diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 3fef920fca..7249cce10e 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -294,7 +294,8 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag // A normal clear will be 2 points, the second point has the color. // We override this value in the pipeline from software transform for clear rectangles. dynState.stencilRef = 0xFF; - dynState.stencilWriteMask = 0xFF; + // But we still apply the stencil write mask. + dynState.stencilWriteMask = (~gstate.getStencilWriteMask()) & 0xFF; } else { key.stencilTestEnable = false; key.stencilCompareOp = VK_COMPARE_OP_ALWAYS; From a99549c4515aeb772fbc35e81a940f242c1362aa Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 17 Mar 2019 06:32:55 -0700 Subject: [PATCH 67/81] UI: Avoid using game info cache in savedata sort. It can change mid-sort causing the sorting results to be inconsistent, which will crash many implementations of std::stable_sort. Also, fix an issue where it kept resorting after it didn't need to and make it strictly ordered for equal dates/sizes. Fixes #11892. --- UI/GameInfoCache.cpp | 18 +--------- UI/SavedataScreen.cpp | 62 +++++++++++++++++++++-------------- ext/native/file/file_util.cpp | 16 +++++++++ ext/native/file/file_util.h | 3 +- 4 files changed, 57 insertions(+), 42 deletions(-) diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 05558dd2b9..eec7f6f340 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -110,27 +110,11 @@ bool GameInfo::Delete() { } } -static int64_t GetDirectoryRecursiveSize(const std::string &path) { - std::vector fileInfo; - getFilesInDir(path.c_str(), &fileInfo); - int64_t sizeSum = 0; - // Note: getFileInDir does not fill in fileSize properly. - for (size_t i = 0; i < fileInfo.size(); i++) { - FileInfo finfo; - getFileInfo(fileInfo[i].fullName.c_str(), &finfo); - if (!finfo.isDirectory) - sizeSum += finfo.size; - else - sizeSum += GetDirectoryRecursiveSize(finfo.fullName); - } - return sizeSum; -} - u64 GameInfo::GetGameSizeInBytes() { switch (fileType) { case IdentifiedFileType::PSP_PBP_DIRECTORY: case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY: - return GetDirectoryRecursiveSize(ResolvePBPDirectory(filePath_)); + return getDirectoryRecursiveSize(ResolvePBPDirectory(filePath_), nullptr, GETFILES_GETHIDDEN); default: return GetFileLoader()->FileSize(); diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index a017aa540d..735b57d5ed 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -132,8 +132,9 @@ public: : UI::LinearLayout(orientation, layoutParams) { } - void SetCompare(CompareFunc lessFunc, DoneFunc) { + void SetCompare(CompareFunc lessFunc, DoneFunc doneFunc) { lessFunc_ = lessFunc; + doneFunc_ = doneFunc; } void Update() override; @@ -336,43 +337,56 @@ bool SavedataBrowser::ByFilename(const UI::View *v1, const UI::View *v2) { return strcmp(b1->GamePath().c_str(), b2->GamePath().c_str()) < 0; } +static time_t GetTotalSize(const SavedataButton *b) { + auto fileLoader = std::unique_ptr(ConstructFileLoader(b->GamePath())); + tm datetm; + bool success; + switch (Identify_File(fileLoader.get())) { + case IdentifiedFileType::PSP_PBP_DIRECTORY: + case IdentifiedFileType::PSP_SAVEDATA_DIRECTORY: + return getDirectoryRecursiveSize(ResolvePBPDirectory(b->GamePath()), nullptr, GETFILES_GETHIDDEN); + + default: + return fileLoader->FileSize(); + } +} + bool SavedataBrowser::BySize(const UI::View *v1, const UI::View *v2) { const SavedataButton *b1 = static_cast(v1); const SavedataButton *b2 = static_cast(v2); - std::shared_ptr g1info = g_gameInfoCache->GetInfo(nullptr, b1->GamePath(), GAMEINFO_WANTSIZE); - std::shared_ptr g2info = g_gameInfoCache->GetInfo(nullptr, b2->GamePath(), GAMEINFO_WANTSIZE); + if (GetTotalSize(b1) > GetTotalSize(b2)) + return true; + return strcmp(b1->GamePath().c_str(), b2->GamePath().c_str()) < 0; +} - // They might be zero, but that's fine. - return g1info->gameSize > g2info->gameSize; +static time_t GetDateSeconds(const SavedataButton *b) { + auto fileLoader = std::unique_ptr(ConstructFileLoader(b->GamePath())); + tm datetm; + bool success; + if (Identify_File(fileLoader.get()) == IdentifiedFileType::PSP_SAVEDATA_DIRECTORY) { + success = File::GetModifTime(b->GamePath() + "/PARAM.SFO", datetm); + } else { + success = File::GetModifTime(b->GamePath(), datetm); + } + + if (success) { + return mktime(&datetm); + } + return (time_t)0; } bool SavedataBrowser::ByDate(const UI::View *v1, const UI::View *v2) { const SavedataButton *b1 = static_cast(v1); const SavedataButton *b2 = static_cast(v2); - auto getDateSeconds = [&](const SavedataButton *b) { - std::shared_ptr ginfo = g_gameInfoCache->GetInfo(nullptr, b->GamePath(), 0); - tm datetm; - bool success; - if (ginfo && ginfo->fileType == IdentifiedFileType::PSP_SAVEDATA_DIRECTORY) { - success = File::GetModifTime(b->GamePath() + "/PARAM.SFO", datetm); - } else { - success = File::GetModifTime(b->GamePath(), datetm); - } - - if (success) { - return mktime(&datetm); - } - return (time_t)0; - }; - - return getDateSeconds(b1) > getDateSeconds(b2); + if (GetDateSeconds(b1) > GetDateSeconds(b2)) + return true; + return strcmp(b1->GamePath().c_str(), b2->GamePath().c_str()) < 0; } bool SavedataBrowser::SortDone() { - PrioritizedWorkQueue *wq = g_gameInfoCache->WorkQueue(); - return wq->Done(); + return true; } void SavedataBrowser::Refresh() { diff --git a/ext/native/file/file_util.cpp b/ext/native/file/file_util.cpp index 0882213e9b..2d6c6df33c 100644 --- a/ext/native/file/file_util.cpp +++ b/ext/native/file/file_util.cpp @@ -297,6 +297,22 @@ size_t getFilesInDir(const char *directory, std::vector *files, const return foundEntries; } +int64_t getDirectoryRecursiveSize(const std::string &path, const char *filter, int flags) { + std::vector fileInfo; + getFilesInDir(path.c_str(), &fileInfo, filter, flags); + int64_t sizeSum = 0; + // Note: getFileInDir does not fill in fileSize properly. + for (size_t i = 0; i < fileInfo.size(); i++) { + FileInfo finfo; + getFileInfo(fileInfo[i].fullName.c_str(), &finfo); + if (!finfo.isDirectory) + sizeSum += finfo.size; + else + sizeSum += getDirectoryRecursiveSize(finfo.fullName, filter, flags); + } + return sizeSum; +} + #ifdef _WIN32 // Returns a vector with the device names std::vector getWindowsDrives() diff --git a/ext/native/file/file_util.h b/ext/native/file/file_util.h index 587b7b93fc..b6c414139b 100644 --- a/ext/native/file/file_util.h +++ b/ext/native/file/file_util.h @@ -34,7 +34,8 @@ FILE *openCFile(const std::string &filename, const char *mode); enum { GETFILES_GETHIDDEN = 1 }; -size_t getFilesInDir(const char *directory, std::vector *files, const char *filter = 0, int flags = 0); +size_t getFilesInDir(const char *directory, std::vector *files, const char *filter = nullptr, int flags = 0); +int64_t getDirectoryRecursiveSize(const std::string &path, const char *filter = nullptr, int flags = 0); #ifdef _WIN32 std::vector getWindowsDrives(); From d83fe7f53cdad50f3df73c2afc008a5b1dbec6e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 21 Mar 2019 20:15:47 +0100 Subject: [PATCH 68/81] Update lang (with ES spelling error fix, etc). Fixes #11912 --- assets/lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lang b/assets/lang index 18e0d460e1..86c62b9a23 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit 18e0d460e187556e9510e2e9b5ae85fa435cefd9 +Subproject commit 86c62b9a23936d556ea0899673f7b078a2f12224 From 926b9e66da5e7c9ac84e0f64d8df9ebdcc3482b0 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 Mar 2019 19:49:32 -0700 Subject: [PATCH 69/81] UI: Allow deletion of GE dumps from UI. --- UI/GameInfoCache.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index eec7f6f340..7070139a4c 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -88,6 +88,7 @@ bool GameInfo::Delete() { case IdentifiedFileType::ARCHIVE_RAR: case IdentifiedFileType::ARCHIVE_ZIP: case IdentifiedFileType::ARCHIVE_7Z: + case IdentifiedFileType::PPSSPP_GE_DUMP: { const std::string &fileToRemove = filePath_; File::Delete(fileToRemove); From c7c45f0acaa115e1c595232d370c6585d1d27578 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Mar 2019 07:25:58 -0700 Subject: [PATCH 70/81] http: Fix warning on compare in url decode. --- ext/native/net/url.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/native/net/url.cpp b/ext/native/net/url.cpp index a2735cf124..32311c4354 100644 --- a/ext/native/net/url.cpp +++ b/ext/native/net/url.cpp @@ -83,8 +83,8 @@ std::string UriDecode(const std::string & sSrc) if (*pSrc == '%') { char dec1, dec2; - if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)]) - && -1 != (dec2 = HEX2DEC[*(pSrc + 2)])) + if (N1 != (dec1 = HEX2DEC[*(pSrc + 1)]) + && N1 != (dec2 = HEX2DEC[*(pSrc + 2)])) { *pEnd++ = (dec1 << 4) + dec2; pSrc += 3; From ff9911deb5e9143ffd9e38abf27ff62635670ff2 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Mar 2019 07:26:47 -0700 Subject: [PATCH 71/81] SDL: Fix compile error when not using FBDEV. --- SDL/SDLGLGraphicsContext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index 1f3269a4df..12d43f790b 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -167,7 +167,7 @@ EGLConfig EGL_FindConfig(int *contextVersion) { return best; } -int8_t EGL_Init() { +int8_t EGL_Init(SDL_Window *window) { int contextVersion = 0; EGLConfig eglConfig = EGL_FindConfig(&contextVersion); if (!eglConfig) { @@ -316,7 +316,7 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std: SDL_ShowWindow(window); #ifdef USING_EGL - if (EGL_Init() != 0) { + if (EGL_Init(window) != 0) { printf("EGL_Init() failed\n"); return 1; } From 3e4faea6adcb38aea3f671e9ac6226dc7fffb656 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Mar 2019 07:27:29 -0700 Subject: [PATCH 72/81] cmake: Automatically disable Wayland for Raspbian. Also add a shortcut to b.sh since it has its own toolchain file. --- CMakeLists.txt | 2 +- SDL/SDLMain.cpp | 1 - b.sh | 6 ++++++ cmake/Toolchains/raspberry.armv6.cmake | 2 +- cmake/Toolchains/raspberry.armv7.cmake | 1 + 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d443e1ee8..89ec8303c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,7 +108,7 @@ option(USING_EGL "Set to ON if target environment uses EGL" ${USING_EGL}) option(USING_FBDEV "Set to ON if target environment uses fbdev (eg. Pandora)" ${USING_FBDEV}) option(USING_GLES2 "Set to ON if target device uses OpenGL ES 2.0" ${USING_GLES2}) option(USING_X11_VULKAN "Set to OFF if target environment doesn't use X11 for Vulkan" ON) -option(USE_WAYLAND_WSI "Enable or disable Wayland WSI support for Vulkan" ON) +option(USE_WAYLAND_WSI "Enable or disable Wayland WSI support for Vulkan" ${USE_WAYLAND_WSI}) # :: Frontends option(USING_QT_UI "Set to ON if you wish to use the Qt frontend wrapper" ${USING_QT_UI}) option(MOBILE_DEVICE "Set to ON when targeting a mobile device" ${MOBILE_DEVICE}) diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 7c4ae4074d..a476008754 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -1,6 +1,5 @@ // SDL/EGL implementation of the framework. // This is quite messy due to platform-specific implementations and #ifdef's. -// Note: SDL1.2 implementation is deprecated and will soon be replaced by SDL2.0. // If your platform is not supported, it is suggested to use Qt instead. #include diff --git a/b.sh b/b.sh index fc0d02d50e..1812333e88 100755 --- a/b.sh +++ b/b.sh @@ -16,6 +16,12 @@ do --ios) CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/Toolchains/ios.cmake ${CMAKE_ARGS}" TARGET_OS=iOS ;; + --rpi-armv6) + CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/Toolchains/raspberry.armv6.cmake ${CMAKE_ARGS}" + ;; + --rpi) + CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/Toolchains/raspberry.armv7.cmake ${CMAKE_ARGS}" + ;; --android) CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=android/android.toolchain.cmake ${CMAKE_ARGS}" TARGET_OS=Android PACKAGE=1 diff --git a/cmake/Toolchains/raspberry.armv6.cmake b/cmake/Toolchains/raspberry.armv6.cmake index 3d93462dab..6167d90f73 100644 --- a/cmake/Toolchains/raspberry.armv6.cmake +++ b/cmake/Toolchains/raspberry.armv6.cmake @@ -23,4 +23,4 @@ set(OPENGL_LIBRARIES brcmGLESv2 bcm_host) set(EGL_LIBRARIES brcmEGL) set(USING_GLES2 ON) set(USING_FBDEV ON) - +set(USE_WAYLAND_WSI OFF) diff --git a/cmake/Toolchains/raspberry.armv7.cmake b/cmake/Toolchains/raspberry.armv7.cmake index eaff3d479d..31b8b77c96 100644 --- a/cmake/Toolchains/raspberry.armv7.cmake +++ b/cmake/Toolchains/raspberry.armv7.cmake @@ -25,3 +25,4 @@ set(EGL_LIBRARIES brcmEGL) set(USING_GLES2 ON) set(USING_FBDEV ON) set(ARMV7 ON) +set(USE_WAYLAND_WSI OFF) From f042dc1773a9bc82293a627248075e294e941e35 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Mar 2019 08:32:18 -0700 Subject: [PATCH 73/81] SDL: Make it clear Vulkan check is not an error. --- SDL/SDLMain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index a476008754..bab2d1bb5d 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -350,9 +350,9 @@ int main(int argc, char *argv[]) { SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); if (VulkanMayBeAvailable()) { - printf("Vulkan might be available.\n"); + printf("DEBUG: Vulkan might be available.\n"); } else { - printf("Vulkan is not available.\n"); + printf("DEBUG: Vulkan is not available, not using Vulkan.\n"); } int set_xres = -1; From f244b390aed06b56ac821910110d357d0993eacf Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Mar 2019 12:05:06 -0700 Subject: [PATCH 74/81] Kernel: Kernel threads can beget kernel threads. Fixes #7687. --- Core/HLE/sceKernelModule.cpp | 9 +++++---- Core/HLE/sceKernelThread.cpp | 8 +++++--- Core/HLE/sceKernelThread.h | 2 +- Core/HLE/sceNetAdhoc.cpp | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 55366beef4..36241fece3 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1934,7 +1934,8 @@ static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 ret if (module->nm.module_start_func != 0 && module->nm.module_start_func != (u32)-1) { entryAddr = module->nm.module_start_func; - attribute = module->nm.module_start_thread_attr; + if (module->nm.module_start_thread_attr != 0) + attribute = module->nm.module_start_thread_attr; } else if ((entryAddr == (u32)-1) || entryAddr == module->memoryBlockAddr - 1) { @@ -1967,7 +1968,7 @@ static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 ret stacksize = module->nm.module_start_thread_stacksize; } - SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, entryAddr, priority, stacksize, attribute, 0); + SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, entryAddr, priority, stacksize, attribute, 0, (module->nm.attribute & 0x1000) != 0); __KernelStartThreadValidate(threadID, argsize, argAddr); __KernelSetThreadRA(threadID, NID_MODULERETURN); __KernelWaitCurThread(WAITTYPE_MODULE, moduleId, 1, 0, false, "started module"); @@ -2049,7 +2050,7 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur if (Memory::IsValidAddress(stopFunc)) { - SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, stopFunc, priority, stacksize, attr, 0); + SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, stopFunc, priority, stacksize, attr, 0, (module->nm.attribute & 0x1000) != 0); __KernelStartThreadValidate(threadID, argSize, argAddr); __KernelSetThreadRA(threadID, NID_MODULERETURN); __KernelWaitCurThread(WAITTYPE_MODULE, moduleId, 1, 0, false, "stopped module"); @@ -2132,7 +2133,7 @@ u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize, } if (Memory::IsValidAddress(stopFunc)) { - SceUID threadID = __KernelCreateThread(module->nm.name, moduleID, stopFunc, priority, stacksize, attr, 0); + SceUID threadID = __KernelCreateThread(module->nm.name, moduleID, stopFunc, priority, stacksize, attr, 0, (module->nm.attribute & 0x1000) != 0); __KernelStartThreadValidate(threadID, argSize, argp); __KernelSetThreadRA(threadID, NID_MODULERETURN); __KernelWaitCurThread(WAITTYPE_MODULE, moduleID, 1, 0, false, "unloadstopped module"); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 28cf1b7442..a909cc3687 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1943,7 +1943,7 @@ SceUID __KernelCreateThreadInternal(const char *threadName, SceUID moduleID, u32 return id; } -int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr) { +int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr, bool allowKernel) { if (threadName == nullptr) return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ERROR, "NULL thread name"); @@ -1960,7 +1960,7 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 if (entry != 0) return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid thread entry %08x", entry); } - if ((attr & ~PSP_THREAD_ATTR_USER_MASK) != 0) + if ((attr & ~PSP_THREAD_ATTR_USER_MASK) != 0 && !allowKernel) return hleReportWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ATTR, "illegal thread attributes %08x", attr); if ((attr & ~PSP_THREAD_ATTR_SUPPORTED) != 0) @@ -1996,7 +1996,9 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 } int sceKernelCreateThread(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr) { - return __KernelCreateThread(threadName, __KernelGetCurThreadModuleId(), entry, prio, stacksize, attr, optionAddr); + Thread *cur = __GetCurrentThread(); + bool allowKernel = cur ? (cur->nt.attr & PSP_THREAD_ATTR_KERNEL) != 0 : false; + return __KernelCreateThread(threadName, __KernelGetCurThreadModuleId(), entry, prio, stacksize, attr, optionAddr, allowKernel); } int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs) { diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 6216fc02ec..a7a127f638 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -31,7 +31,7 @@ class DebugInterface; int sceKernelChangeThreadPriority(SceUID threadID, int priority); SceUID __KernelCreateThreadInternal(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr); -int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr); +int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr, bool allowKernel); int sceKernelCreateThread(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr); int sceKernelDelayThread(u32 usec); int sceKernelDelayThreadCB(u32 usec); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 7b1f7049a1..6e66350b50 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -174,7 +174,7 @@ u32 sceNetAdhocInit() { // TODO: Should use a separated threads for friendFinder, matchingEvent, and matchingInput and created on AdhocctlInit & AdhocMatchingStart instead of here #define PSP_THREAD_ATTR_KERNEL 0x00001000 // PSP_THREAD_ATTR_KERNEL is located in sceKernelThread.cpp instead of sceKernelThread.h :( //threadAdhocID = __KernelCreateThreadInternal("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, 0x30, 4096, PSP_THREAD_ATTR_KERNEL); - threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, 0x10, 0x1000, 0, 0); + threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, 0x10, 0x1000, 0, 0, false); if (threadAdhocID > 0) { __KernelStartThread(threadAdhocID, 0, 0); } From 812e84e4a70ad73e5cf63bba8a3c36c7eb849b13 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Mar 2019 12:12:13 -0700 Subject: [PATCH 75/81] Android: Allow less common sample rates. Just assume anything we received is a valid one. --- android/jni/native-audio-so.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/android/jni/native-audio-so.cpp b/android/jni/native-audio-so.cpp index 4fbb492d28..607142f022 100644 --- a/android/jni/native-audio-so.cpp +++ b/android/jni/native-audio-so.cpp @@ -23,10 +23,6 @@ AudioContext::AudioContext(AndroidAudioCallback cb, int _FramesPerBuffer, int _S framesPerBuffer = 4096; sampleRate = _SampleRate; - if (sampleRate != 44100 && sampleRate != 48000) { - ELOG("Invalid sample rate %i - choosing 44100", sampleRate); - sampleRate = 44100; - } } // This callback handler is called every time a buffer finishes playing. @@ -84,10 +80,8 @@ bool OpenSLContext::Init() { result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); assert(SL_RESULT_SUCCESS == result); - SLuint32 sr = SL_SAMPLINGRATE_44_1; - if (sampleRate == 48000) { - sr = SL_SAMPLINGRATE_48; - } // Don't allow any other sample rates. + // The constants, such as SL_SAMPLINGRATE_44_1, are just 44100000. + SLuint32 sr = (SLuint32)sampleRate * 1000; SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; SLDataFormat_PCM format_pcm = { From 4c3aa841d39121c88bc8f067d4d11af37bddb302 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 Mar 2019 15:18:45 -0700 Subject: [PATCH 76/81] IR: Correct vmmul optimizations. It's a bit confusing since it's not D = S*T, but rather D = S'*T. --- Core/MIPS/IR/IRCompVFPU.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Core/MIPS/IR/IRCompVFPU.cpp b/Core/MIPS/IR/IRCompVFPU.cpp index f3019f9f50..6393fff4a9 100644 --- a/Core/MIPS/IR/IRCompVFPU.cpp +++ b/Core/MIPS/IR/IRCompVFPU.cpp @@ -1174,9 +1174,14 @@ namespace MIPSComp { // Many more instructions to interpret. void IRFrontend::Comp_Vmmul(MIPSOpcode op) { CONDITIONAL_DISABLE(VFPU_MTX); + if (!js.HasNoPrefix()) { + DISABLE; + } - // Matrix multiply (no prefixes) - // D[0 .. N,0 .. M] = S[0 .. N, 0 .. M] * T[0 .. N,0 .. M] + // Matrix multiply (wierd prefixes) + // D[0 .. N, 0 .. M] = S[0 .. N, 0 .. M]' * T[0 .. N, 0 .. M] + // Note: Behaves as if it's implemented through a series of vdots. + // Important: this is a matrix multiply with a pre-transposed S. MatrixSize sz = GetMtxSize(op); int n = GetMatrixSide(sz); @@ -1229,7 +1234,7 @@ namespace MIPSComp { // TODO: Skip this and resort to method one and transpose the output? for (int j = 0; j < 4; j++) { for (int i = 0; i < 4; i++) { - ir.Write(IROp::Vec4Dot, s0 + i, sregs[i], tregs[j * 4]); + ir.Write(IROp::Vec4Dot, s0 + i, sregs[i * 4], tregs[j * 4]); } ir.Write(IROp::Vec4Mov, dregs[j * 4], s0); } From 703fdc5561a699fe2d3ad838ffc1c0ae4f4e216c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Mar 2019 11:16:04 +0100 Subject: [PATCH 77/81] MSVC project files: Fix silly search/replace error from #11883 --- ext/libkirk/libkirk.vcxproj | 2 +- headless/Headless.vcxproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/libkirk/libkirk.vcxproj b/ext/libkirk/libkirk.vcxproj index 036c3f9f68..c26a53464b 100644 --- a/ext/libkirk/libkirk.vcxproj +++ b/ext/libkirk/libkirk.vcxproj @@ -70,7 +70,7 @@ Level3 - EnablePreciseChecks + EnableFastChecks _CRTDBG_MAP_ALLOC;_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS true false diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index 807a5a2856..f2c47e75ad 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -94,7 +94,7 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_32=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS ../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native - EnablePreciseChecks + EnableFastChecks StreamingSIMDExtensions2 Precise true From d3c0a010a08203a0a9bbbac54eca3a13e2f5e540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Mar 2019 11:48:26 +0100 Subject: [PATCH 78/81] Fix invalid argument string for kuKernelLoadModule. Fixes #11895. --- Core/HLE/KUBridge.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/KUBridge.cpp b/Core/HLE/KUBridge.cpp index d9fce045b7..dd643c5896 100644 --- a/Core/HLE/KUBridge.cpp +++ b/Core/HLE/KUBridge.cpp @@ -38,7 +38,7 @@ static int kuKernelGetModel() { const HLEFunction KUBridge[] = { - { 0x4C25EA72, &WrapI_CUU, "kuKernelLoadModule", 'i', "cuu" }, + { 0x4C25EA72, &WrapI_CUU, "kuKernelLoadModule", 'i', "sxx" }, { 0x24331850, &WrapI_V, "kuKernelGetModel", 'i', "" }, }; From 8adb0dfd611bda5ba7d9c2b119b09ba53d0bf91e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 Mar 2019 11:49:22 +0100 Subject: [PATCH 79/81] Vulkan validation: INFO level has gotten too spammy, turn it off. --- Windows/GPU/WindowsVulkanContext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index aa99f66190..59ca85f76e 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -127,9 +127,9 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m if (g_Vulkan->DeviceExtensions().EXT_debug_utils) { int bits = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT - | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - // We're intentionally skipping VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT + // We're intentionally skipping VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT and + // VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, just too spammy. g_Vulkan->InitDebugUtilsCallback(&VulkanDebugUtilsCallback, bits, &g_LogOptions); } else { int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; From f53ea7e44f8c9ee6baf5bbb26d2174e41010e86b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 Mar 2019 12:56:23 -0700 Subject: [PATCH 80/81] Debugger: Prevent saving a -1 sized func. --- Windows/Debugger/CtrlDisAsmView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index fdf4de758c..71fea8b4ac 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -979,8 +979,8 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) std::string newname; truncate_cpy(name, g_symbolMap->GetLabelString(funcBegin).c_str()); if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), L"New function name", name, newname)) { - g_symbolMap->SetLabelName(newname.c_str(),funcBegin); - u32 funcSize = g_symbolMap->GetFunctionSize(curAddress); + g_symbolMap->SetLabelName(newname.c_str(), funcBegin); + u32 funcSize = g_symbolMap->GetFunctionSize(funcBegin); MIPSAnalyst::RegisterFunction(funcBegin, funcSize, newname.c_str()); MIPSAnalyst::UpdateHashMap(); MIPSAnalyst::ApplyHashMap(); From 11990086412591dc06145a7725f4ffa97bbdfad2 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 Mar 2019 19:21:08 -0700 Subject: [PATCH 81/81] TexCache: Align bufw properly even for VRAM. Fixes minimap arrows in Manhunt 2 (see #9615.) --- GPU/Common/TextureDecoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Common/TextureDecoder.cpp b/GPU/Common/TextureDecoder.cpp index 9e896872fe..b4bf87adfa 100644 --- a/GPU/Common/TextureDecoder.cpp +++ b/GPU/Common/TextureDecoder.cpp @@ -89,7 +89,7 @@ static const u32 textureAlignMask16[16] = { u32 GetTextureBufw(int level, u32 texaddr, GETextureFormat format) { // This is a hack to allow for us to draw the huge PPGe texture, which is always in kernel ram. - if (texaddr < PSP_GetKernelMemoryEnd()) + if (texaddr >= PSP_GetKernelMemoryBase() && texaddr < PSP_GetKernelMemoryEnd()) return gstate.texbufwidth[level] & 0x1FFF; u32 bufw = gstate.texbufwidth[level] & textureAlignMask16[format];